<template>
  <div class="reading-learning">
    <!-- 页面头部 -->
    <div class="page-header">
      <button class="back-btn" @click="goBack">
        ← 返回
      </button>
      <h1>📚 绘本阅读</h1>
    </div>

    <!-- 标签页导航 -->
    <div class="tabs-nav">
      <button
        :class="['tab-btn', { active: currentTab === 'bookshelf' }]"
        @click="currentTab = 'bookshelf'"
      >
        📖 书架
      </button>
      <button
        :class="['tab-btn', { active: currentTab === 'report' }]"
        @click="currentTab = 'report'"
      >
        📊 报告
      </button>
    </div>

    <!-- 绘本书架界面 -->
    <div v-if="currentTab === 'bookshelf'" class="bookshelf-container">
      <div class="bookshelf-card">
        <!-- 书架背景 -->
        <div class="bookshelf-background">
          <div class="shelf shelf-1"></div>
          <div class="shelf shelf-2"></div>
          <div class="shelf shelf-3"></div>
        </div>

        <!-- 加载提示 -->
        <div v-if="loading" class="loading-container">
          <div class="loading-text">正在加载推荐绘本...</div>
        </div>
        
        <!-- 按难度分组的绘本列表 -->
        <div v-else class="books-by-difficulty">
          <!-- 简单难度 -->
          <div v-if="booksByDifficulty.easy.length > 0" class="difficulty-section">
            <div class="difficulty-header difficulty-easy-header">
              <span class="difficulty-icon">📖</span>
              <span class="difficulty-title">简单</span>
              <span class="difficulty-count">({{ booksByDifficulty.easy.length }}本)</span>
            </div>
            <div class="books-grid">
              <div
                v-for="book in booksByDifficulty.easy"
                :key="book.id"
                :class="['book-item', { completed: book.progress === 100 }]"
                @click="openBook(book)"
              >
                <!-- 绘本封面 -->
                <div class="book-cover">
                  <div class="cover-image" :style="getBookCoverStyle(book)">
                    <div v-if="!book.cover || !isValidImageUrl(book.cover)" class="cover-placeholder" :style="getBookGradientStyle(book)">
                      <div class="cover-icon">{{ getBookEmoji(book) }}</div>
                    </div>
                  </div>
                  <!-- 难度角标 -->
                  <div class="difficulty-badge difficulty-easy">
                    简单
                  </div>
                  <!-- 进度贴纸 -->
                  <div v-if="book.progress > 0" class="progress-sticker" :class="{ completed: book.progress === 100 }">
                    <span v-if="book.progress === 100">✓ 已读完</span>
                    <span v-else>{{ book.progress }}%</span>
                  </div>
                </div>
                <!-- 绘本标题 -->
                <div class="book-title">{{ book.title }}</div>
              </div>
            </div>
          </div>

          <!-- 中等难度 -->
          <div v-if="booksByDifficulty.medium.length > 0" class="difficulty-section">
            <div class="difficulty-header difficulty-medium-header">
              <span class="difficulty-icon">📚</span>
              <span class="difficulty-title">中等</span>
              <span class="difficulty-count">({{ booksByDifficulty.medium.length }}本)</span>
            </div>
            <div class="books-grid">
              <div
                v-for="book in booksByDifficulty.medium"
                :key="book.id"
                :class="['book-item', { completed: book.progress === 100 }]"
                @click="openBook(book)"
              >
                <!-- 绘本封面 -->
                <div class="book-cover">
                  <div class="cover-image" :style="getBookCoverStyle(book)">
                    <div v-if="!book.cover || !isValidImageUrl(book.cover)" class="cover-placeholder" :style="getBookGradientStyle(book)">
                      <div class="cover-icon">{{ getBookEmoji(book) }}</div>
                    </div>
                  </div>
                  <!-- 难度角标 -->
                  <div class="difficulty-badge difficulty-medium">
                    中等
                  </div>
                  <!-- 进度贴纸 -->
                  <div v-if="book.progress > 0" class="progress-sticker" :class="{ completed: book.progress === 100 }">
                    <span v-if="book.progress === 100">✓ 已读完</span>
                    <span v-else>{{ book.progress }}%</span>
                  </div>
                </div>
                <!-- 绘本标题 -->
                <div class="book-title">{{ book.title }}</div>
              </div>
            </div>
          </div>

          <!-- 困难难度 -->
          <div v-if="booksByDifficulty.hard.length > 0" class="difficulty-section">
            <div class="difficulty-header difficulty-hard-header">
              <span class="difficulty-icon">📘</span>
              <span class="difficulty-title">困难</span>
              <span class="difficulty-count">({{ booksByDifficulty.hard.length }}本)</span>
            </div>
            <div class="books-grid">
              <div
                v-for="book in booksByDifficulty.hard"
                :key="book.id"
                :class="['book-item', { completed: book.progress === 100 }]"
                @click="openBook(book)"
              >
                <!-- 绘本封面 -->
                <div class="book-cover">
                  <div class="cover-image" :style="getBookCoverStyle(book)">
                    <div v-if="!book.cover || !isValidImageUrl(book.cover)" class="cover-placeholder" :style="getBookGradientStyle(book)">
                      <div class="cover-icon">{{ getBookEmoji(book) }}</div>
                    </div>
                  </div>
                  <!-- 难度角标 -->
                  <div class="difficulty-badge difficulty-hard">
                    困难
                  </div>
                  <!-- 进度贴纸 -->
                  <div v-if="book.progress > 0" class="progress-sticker" :class="{ completed: book.progress === 100 }">
                    <span v-if="book.progress === 100">✓ 已读完</span>
                    <span v-else>{{ book.progress }}%</span>
                  </div>
                </div>
                <!-- 绘本标题 -->
                <div class="book-title">{{ book.title }}</div>
              </div>
            </div>
          </div>

          <!-- 空状态 -->
          <div v-if="booksByDifficulty.easy.length === 0 && booksByDifficulty.medium.length === 0 && booksByDifficulty.hard.length === 0" class="empty-state">
            <div class="empty-icon">📚</div>
            <div class="empty-text">暂无推荐绘本</div>
          </div>
        </div>
      </div>
    </div>

    <!-- 阅读器界面 -->
    <div v-if="currentTab === 'reader' && currentBook" class="reader-container">
      <!-- 阅读器主界面 -->
      <div class="reader-card">
        <!-- 阅读器头部 -->
        <div class="reader-header">
          <div class="reader-title-section">
            <h2 class="reader-title">{{ currentBook.title }}</h2>
            <div class="reader-mode-badge">
              <span class="mode-badge-icon">👨‍👩‍👧</span>
              <span class="mode-badge-text">伴读模式</span>
            </div>
          </div>
          <div class="reader-header-right">
            <button
              :class="['auto-play-btn-header', { active: isAutoPlaying }]"
              @click="toggleAutoPlay"
              :title="isAutoPlaying ? '停止自动播放' : '自动播放本页'"
            >
              <span class="auto-play-icon-header">{{ isAutoPlaying ? '⏸️' : '▶️' }}</span>
              <span class="auto-play-text-header">{{ isAutoPlaying ? '停止' : '自动播放' }}</span>
            </button>
            <div class="reader-progress">
              <span>第 {{ currentPage + 1 }} / {{ currentBook.pages.length }} 页</span>
            </div>
          </div>
        </div>

        <!-- 阅读内容区域 -->
        <div class="reader-content">
          <!-- 左侧：绘本插图 -->
          <div class="reader-image-section">
            <div class="book-image">
              <img
                :src="getPageImage(currentBook.pages[currentPage])"
                :alt="`第${currentPage + 1}页`"
                @error="handleImageError"
              />
            </div>
          </div>

          <!-- 右侧：英文文本 -->
          <div class="reader-text-section">
            <div class="text-content">
              <div
                v-for="(sentence, index) in currentBook.pages[currentPage]?.sentences || []"
                :key="index"
                class="sentence-wrapper"
              >
                <div
                  :class="['sentence-item', { active: currentSentenceIndex === index, highlighted: currentSentenceIndex === index }]"
                  @click="handleSentenceClick(index, $event)"
                >
                  <span class="sentence-text">{{ sentence.text }}</span>
                  <div class="sentence-actions">
                    <button class="action-btn play-btn" @click.stop="playSentence(index)" :title="'播放音频'">
                      🔊
                    </button>
                    <button
                      class="action-btn translate-btn"
                      @click.stop.prevent="toggleTranslation(currentPage, index, sentence.text, $event)"
                      :title="isShowingTranslation(currentPage, index) ? '隐藏翻译' : '显示翻译'"
                    >
                      {{ isShowingTranslation(currentPage, index) ? '🔽' : '🌐' }}
                    </button>
                    <button
                      v-if="readingMode === 'accompany'"
                      class="action-btn follow-btn"
                      @click.stop="startFollowRead(index)"
                      :title="'跟读练习，检查发音'"
                    >
                      🎤
                    </button>
                  </div>
                </div>
                <!-- 翻译显示区域 -->
                <div v-if="isShowingTranslation(currentPage, index)" class="sentence-translation">
                  <span class="translation-label">翻译：</span>
                  <span>{{ getTranslation(currentPage, index, sentence.text) }}</span>
                </div>
              </div>
            </div>
            
            <!-- 整页跟读按钮（放在右侧空白处） -->
            <div v-if="readingMode === 'accompany'" class="page-follow-read-section-right">
              <button 
                class="page-follow-read-btn-right"
                @click="startPageFollowRead"
                :disabled="isPageRecording"
              >
                <span class="btn-icon">🎙️</span>
                <span class="btn-text">{{ isPageRecording ? '正在录音...' : '整页跟读' }}</span>
              </button>
            </div>
          </div>
        </div>

        <!-- 家长提示和跟读反馈（伴读模式） -->
        <div v-if="readingMode === 'accompany'" class="accompany-mode-footer">
          <!-- 家长提示 -->
          <div v-if="currentBook.pages[currentPage]?.parentTip" class="parent-tip">
            <div class="tip-icon">💡</div>
            <div class="tip-content">
              <div class="tip-title">家长提示</div>
              <div class="tip-text">{{ currentBook.pages[currentPage].parentTip }}</div>
            </div>
          </div>
          
          <!-- 整页跟读反馈区域 -->
          <div v-if="pageFollowReadResult" class="follow-read-result page-result">
            <div class="result-clickable-area clickable" @click="showPronunciationDetails('page')">
              <div class="result-icon" :class="pageFollowReadResult.score >= 80 ? 'result-good' : 'result-need-improve'">
                {{ pageFollowReadResult.score >= 80 ? '✅' : '📝' }}
              </div>
              <div class="result-content">
                <div class="result-title">
                  {{ pageFollowReadResult.score >= 80 ? '整页发音很棒！' : '继续加油！' }}
                  <span class="click-hint">👆 点击查看详情</span>
                </div>
                <div class="result-score">整页准确率: {{ pageFollowReadResult.score }}%</div>
                <div v-if="pageFollowReadResult.feedback" class="result-feedback">{{ pageFollowReadResult.feedback }}</div>
              </div>
            </div>
            <!-- 历史记录切换 -->
            <div v-if="pageFollowReadResults.length > 1" class="result-history-controls">
              <button 
                class="history-btn" 
                @click.stop.prevent="switchPageResult(-1, $event)"
                :disabled="currentPageFollowReadResultIndex <= 0"
                title="上一条记录"
              >
                ←
              </button>
              <span class="history-indicator">
                {{ currentPageFollowReadResultIndex + 1 }} / {{ pageFollowReadResults.length }}
              </span>
              <button 
                class="history-btn" 
                @click.stop.prevent="switchPageResult(1, $event)"
                :disabled="currentPageFollowReadResultIndex >= pageFollowReadResults.length - 1"
                title="下一条记录"
              >
                →
              </button>
            </div>
          </div>
          
          <!-- 单句跟读反馈区域 -->
          <div v-if="followReadResult && !pageFollowReadResult" class="follow-read-result">
            <div class="result-clickable-area clickable" @click="showPronunciationDetails('sentence')">
              <div class="result-icon" :class="followReadResult.score >= 80 ? 'result-good' : 'result-need-improve'">
                {{ followReadResult.score >= 80 ? '✅' : '📝' }}
              </div>
              <div class="result-content">
                <div class="result-title">
                  {{ followReadResult.score >= 80 ? '发音很棒！' : '继续加油！' }}
                  <span class="click-hint">👆 点击查看详情</span>
                </div>
                <div class="result-score">准确率: {{ followReadResult.score }}%</div>
                <div v-if="followReadResult.feedback" class="result-feedback">{{ followReadResult.feedback }}</div>
              </div>
            </div>
            <!-- 历史记录切换 -->
            <div v-if="followReadResults.length > 1" class="result-history-controls">
              <button 
                class="history-btn" 
                @click.stop.prevent="switchFollowReadResult(-1, $event)"
                :disabled="currentFollowReadResultIndex <= 0"
                title="上一条记录"
              >
                ←
              </button>
              <span class="history-indicator">
                {{ currentFollowReadResultIndex + 1 }} / {{ followReadResults.length }}
              </span>
              <button 
                class="history-btn" 
                @click.stop.prevent="switchFollowReadResult(1, $event)"
                :disabled="currentFollowReadResultIndex >= followReadResults.length - 1"
                title="下一条记录"
              >
                →
              </button>
            </div>
          </div>
        </div>

        <!-- 阅读器底部控制 -->
        <div class="reader-controls">
          <button class="control-btn" @click="previousPage" :disabled="currentPage === 0">
            ← 上一页
          </button>
          <div class="page-indicator">
            <div
              v-for="(page, index) in currentBook.pages"
              :key="index"
              :class="['page-dot', { active: currentPage === index }]"
              @click="goToPage(index)"
            ></div>
          </div>
          <button class="control-btn" @click="nextPage" :disabled="currentPage === currentBook.pages.length - 1">
            下一页 →
          </button>
        </div>

        <!-- 隐藏的音频元素 -->
        <audio ref="audioPlayer" @ended="onAudioEnded"></audio>
        <audio ref="userRecordingPlayer" @ended="playingAudioUrl = null"></audio>
      </div>
    </div>

    <!-- 跟读模态框 -->
    <div v-if="showFollowReadModal" class="follow-read-modal-overlay" @click.self="closeFollowReadModal">
      <div class="follow-read-modal">
        <div class="modal-header">
          <h3>跟读练习</h3>
          <button class="modal-close-btn" @click="closeFollowReadModal">×</button>
        </div>
        <div class="modal-content">
          <div v-if="currentFollowReadIndex >= 0 && currentBook" class="sentence-to-read">
            <div class="sentence-label">请跟读这句话：</div>
            <div class="sentence-text-large">
              "{{ currentBook.pages[currentPage].sentences[currentFollowReadIndex]?.text }}"
            </div>
          </div>
          
          <div v-if="isRecording" class="recording-status">
            <div class="recording-indicator">
              <div class="recording-dot"></div>
              <span>正在录音中...</span>
            </div>
            <div class="recording-hint">请清晰地朗读上面的句子</div>
          </div>
          
          <div v-if="followReadResult" class="recognition-result">
            <div class="result-header">
              <div class="result-icon-large" :class="followReadResult.score >= 80 ? 'result-good' : 'result-need-improve'">
                {{ followReadResult.score >= 80 ? '✅' : '📝' }}
              </div>
              <div class="result-title-large">
                {{ followReadResult.score >= 80 ? '发音很棒！' : '继续加油！' }}
              </div>
            </div>
            <div class="result-score-large">准确率: {{ followReadResult.score }}%</div>
            <div v-if="followReadResult.feedback" class="result-feedback-large">{{ followReadResult.feedback }}</div>
            <div class="result-details">
              <div class="detail-item">
                <span class="detail-label">识别内容：</span>
                <span class="detail-value">{{ followReadResult.recognizedText }}</span>
              </div>
            </div>
            <!-- 单词级别发音评测 -->
            <div v-if="followReadResult.wordScores && followReadResult.wordScores.length > 0" class="word-scores">
              <div class="word-scores-title">单词发音评测：</div>
              <div class="word-scores-content">
                <span
                  v-for="(wordScore, index) in followReadResult.wordScores"
                  :key="index"
                  class="word-score-item"
                  :class="[getWordScoreClass(wordScore.score), { 'word-clickable': wordScore.score < 80 }]"
                  :title="getWordTitle(wordScore)"
                  @click="handleWordClick(wordScore)"
                >
                  {{ wordScore.word }}
                  <span v-if="wordScore.score < 80" class="word-play-icon">🔊</span>
                </span>
              </div>
            </div>
          </div>
          
          <div v-if="!isRecording && !followReadResult" class="recording-prompt">
            <div class="prompt-icon">🎤</div>
            <div class="prompt-text">3秒后开始录音，请准备...</div>
            <div class="countdown-timer" v-if="showFollowReadModal && !isRecording && !followReadResult && countdown > 0">
              {{ countdown }}
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button v-if="isRecording" class="modal-btn stop-btn" @click="stopRecording">停止录音</button>
          <button v-else-if="!followReadResult" class="modal-btn start-btn" @click="startRecording(currentBook.pages[currentPage].sentences[currentFollowReadIndex]?.text)">重新录音</button>
          <button v-else class="modal-btn close-btn" @click="closeFollowReadModal">关闭</button>
        </div>
      </div>
    </div>

    <!-- 整页跟读模态框 -->
    <div v-if="showPageFollowReadModal" class="follow-read-modal-overlay" @click.self="closePageFollowReadModal">
      <div class="follow-read-modal">
        <div class="modal-header">
          <h3>整页跟读练习</h3>
          <button class="modal-close-btn" @click="closePageFollowReadModal">×</button>
        </div>
        <div class="modal-content">
          <div v-if="currentBook && currentBook.pages[currentPage]" class="sentence-to-read">
            <div class="sentence-label">请跟读整页内容：</div>
            <div class="page-text-large">
              <div 
                v-for="(sentence, index) in currentBook.pages[currentPage].sentences"
                :key="index"
                class="page-sentence-item"
              >
                "{{ sentence.text }}"
              </div>
            </div>
          </div>
          
          <div v-if="isPageRecording" class="recording-status">
            <div class="recording-indicator">
              <div class="recording-dot"></div>
              <span>正在录音中...</span>
            </div>
            <div class="recording-hint">请清晰地朗读整页内容</div>
          </div>
          
          <div v-if="pageFollowReadResult" class="recognition-result">
            <div class="result-header">
              <div class="result-icon-large" :class="pageFollowReadResult.score >= 80 ? 'result-good' : 'result-need-improve'">
                {{ pageFollowReadResult.score >= 80 ? '✅' : '📝' }}
              </div>
              <div class="result-title-large">
                {{ pageFollowReadResult.score >= 80 ? '整页发音很棒！' : '继续加油！' }}
              </div>
            </div>
            <div class="result-score-large">整页准确率: {{ pageFollowReadResult.score }}%</div>
            <div v-if="pageFollowReadResult.feedback" class="result-feedback-large">{{ pageFollowReadResult.feedback }}</div>
            <div class="result-details">
              <div class="detail-item">
                <span class="detail-label">识别内容：</span>
                <span class="detail-value">{{ pageFollowReadResult.recognizedText }}</span>
              </div>
            </div>
            <!-- 单词级别发音评测 -->
            <div v-if="pageFollowReadResult.wordScores && pageFollowReadResult.wordScores.length > 0" class="word-scores">
              <div class="word-scores-title">单词发音评测：</div>
              <div class="word-scores-content">
                <span
                  v-for="(wordScore, index) in pageFollowReadResult.wordScores"
                  :key="index"
                  class="word-score-item"
                  :class="[getWordScoreClass(wordScore.score), { 'word-clickable': wordScore.score < 80 }]"
                  :title="getWordTitle(wordScore)"
                  @click="handleWordClick(wordScore)"
                >
                  {{ wordScore.word }}
                  <span v-if="wordScore.score < 80" class="word-play-icon">🔊</span>
                </span>
              </div>
            </div>
          </div>
          
          <div v-if="!isPageRecording && !pageFollowReadResult" class="recording-prompt">
            <div class="prompt-icon">🎙️</div>
            <div class="prompt-text">3秒后开始录音，请准备...</div>
            <div class="countdown-timer" v-if="showPageFollowReadModal && !isPageRecording && !pageFollowReadResult && pageCountdown > 0">
              {{ pageCountdown }}
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button v-if="isPageRecording" class="modal-btn stop-btn" @click="stopPageRecording">停止录音</button>
          <button v-else-if="!pageFollowReadResult" class="modal-btn start-btn" @click="startPageRecording(getPageText())">重新录音</button>
          <button v-else class="modal-btn close-btn" @click="closePageFollowReadModal">关闭</button>
        </div>
      </div>
    </div>

    <!-- 发音详情模态框 -->
    <div v-if="showPronunciationDetailsModal" class="follow-read-modal-overlay" @click.self="closePronunciationDetailsModal">
      <div class="follow-read-modal pronunciation-details-modal">
        <div class="modal-header">
          <h3>发音详情</h3>
          <button class="modal-close-btn" @click="closePronunciationDetailsModal">×</button>
        </div>
        <div class="modal-content" v-if="currentPronunciationDetails">
          <div class="pronunciation-summary">
            <div class="summary-icon" :class="currentPronunciationDetails.score >= 80 ? 'result-good' : 'result-need-improve'">
              {{ currentPronunciationDetails.score >= 80 ? '✅' : '📝' }}
            </div>
            <div class="summary-content">
              <div class="summary-title">
                {{ currentPronunciationDetails.score >= 80 ? '发音很棒！' : '继续加油！' }}
              </div>
              <div class="summary-score">准确率: {{ currentPronunciationDetails.score }}%</div>
              <div v-if="currentPronunciationDetails.feedback" class="summary-feedback">{{ currentPronunciationDetails.feedback }}</div>
            </div>
          </div>
          
          <div class="pronunciation-details-section">
            <div class="details-item">
              <div class="details-label">期望内容：</div>
              <div class="details-value">{{ currentPronunciationDetails.expectedText }}</div>
            </div>
            <div class="details-item">
              <div class="details-label">识别内容：</div>
              <div class="details-value">{{ currentPronunciationDetails.recognizedText }}</div>
            </div>
            <!-- 用户录音回放 -->
            <div v-if="currentPronunciationDetails.audioUrl" class="details-item audio-playback">
              <div class="details-label">我的录音：</div>
              <button 
                class="play-recording-btn" 
                @click="playUserRecording(currentPronunciationDetails.audioUrl)"
                :title="playingAudioUrl === currentPronunciationDetails.audioUrl ? '停止播放' : '播放我的录音'"
              >
                {{ playingAudioUrl === currentPronunciationDetails.audioUrl ? '⏸️ 停止' : '▶️ 播放' }}
              </button>
            </div>
          </div>
          
          <!-- 单词级别发音评测 -->
          <div v-if="currentPronunciationDetails.wordScores && currentPronunciationDetails.wordScores.length > 0" class="word-scores">
            <div class="word-scores-title">单词发音评测：</div>
            <div class="word-scores-content">
              <div
                v-for="(wordScore, index) in currentPronunciationDetails.wordScores"
                :key="index"
                class="word-score-item-wrapper"
              >
                <span
                  class="word-score-item"
                  :class="[getWordScoreClass(wordScore.score), { 'word-clickable': wordScore.score < 80 }]"
                  :title="getWordTitle(wordScore)"
                  @click="handleWordClick(wordScore)"
                >
                  {{ wordScore.word }}
                  <span v-if="wordScore.score < 80" class="word-play-icon">🔊</span>
                  <span class="word-score-badge">{{ wordScore.score }}%</span>
                </span>
                <span class="word-meaning">{{ getWordMeaning(wordScore.word) }}</span>
              </div>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button class="modal-btn close-btn" @click="closePronunciationDetailsModal">关闭</button>
        </div>
      </div>
    </div>

    <!-- 阅读报告界面 -->
    <div v-if="currentTab === 'report'" class="report-container">
      <div class="report-card">
        <!-- 数据概览 -->
        <div class="report-overview">
          <!-- 本月阅读量勋章 -->
          <div class="stat-badge clickable" @click="openReadingRecords">
            <div class="badge-icon">🏆</div>
            <div class="badge-content">
              <div class="badge-value">{{ monthlyReadCount }}</div>
              <div class="badge-label">本月阅读量</div>
            </div>
          </div>

          <!-- 平均跟读准确率仪表盘 -->
          <div class="stat-gauge clickable" @click="openAccuracyDetails">
            <div class="gauge-header">
              <span class="gauge-icon">📊</span>
              <span class="gauge-title">平均跟读准确率</span>
            </div>
            <div class="gauge-container">
              <div class="gauge-circle">
                <svg class="gauge-svg" viewBox="0 0 120 120">
                  <circle
                    class="gauge-bg"
                    cx="60"
                    cy="60"
                    r="50"
                    fill="none"
                    stroke="#e0e0e0"
                    stroke-width="8"
                  />
                  <circle
                    class="gauge-fill"
                    cx="60"
                    cy="60"
                    r="50"
                    fill="none"
                    stroke="#667eea"
                    stroke-width="8"
                    :stroke-dasharray="`${averageAccuracy * 3.14} 314`"
                    stroke-dashoffset="78.5"
                    transform="rotate(-90 60 60)"
                  />
                </svg>
                <div class="gauge-value">{{ averageAccuracy }}%</div>
              </div>
            </div>
          </div>
        </div>

        <!-- 详细清单 -->
        <div class="report-details" v-show="showReadingRecords || showAccuracyDetails">
          <div class="details-header">
            <h3 class="details-title">{{ showReadingRecords ? '阅读记录' : '跟读详情' }}</h3>
            <button class="close-details-btn" @click="closeDetails">×</button>
          </div>
          
          <!-- 阅读记录 -->
          <div v-if="showReadingRecords" class="reading-records">
            <div
              v-for="record in readingRecords"
              :key="record.id"
              class="record-item"
            >
              <div class="record-book-info">
                <div class="record-cover" :style="getRecordBookCoverStyle(record)">
                  <div v-if="!getRecordBookCover(record)" class="cover-placeholder" :style="getRecordBookGradientStyle(record)">
                    <div class="cover-icon">{{ getRecordBookEmoji(record) }}</div>
                  </div>
                </div>
                <div class="record-info">
                  <div class="record-title">{{ record.bookTitle }}</div>
                  <div class="record-date">{{ record.readDate }}</div>
                </div>
              </div>
              <div class="record-scores">
                <div v-for="(score, index) in record.scores" :key="index" class="score-item">
                  <span class="score-label">第{{ index + 1 }}次</span>
                  <span class="score-value" :class="getScoreClass(score)">{{ score }}%</span>
                </div>
              </div>
            </div>
          </div>
          
          <!-- 跟读详情 -->
          <div v-if="showAccuracyDetails" class="accuracy-details">
            <div
              v-for="record in readingRecords"
              :key="record.id"
              class="accuracy-record-item"
            >
              <div class="accuracy-book-header">
                <div class="accuracy-book-cover" :style="getRecordBookCoverStyle(record)">
                  <div v-if="!getRecordBookCover(record)" class="cover-placeholder" :style="getRecordBookGradientStyle(record)">
                    <div class="cover-icon">{{ getRecordBookEmoji(record) }}</div>
                  </div>
                </div>
                <div class="accuracy-book-info">
                  <div class="accuracy-book-title">{{ record.bookTitle }}</div>
                  <div class="accuracy-book-date">{{ record.readDate }}</div>
                </div>
              </div>
              <div class="accuracy-scores-list">
                <div v-for="(score, index) in record.scores" :key="index" class="accuracy-score-item">
                  <div class="accuracy-attempt">第{{ index + 1 }}次跟读</div>
                  <div class="accuracy-score-value" :class="getScoreClass(score)">
                    <span class="score-number">{{ score }}%</span>
                    <span class="score-status">{{ getScoreStatus(score) }}</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { childEnglishApi } from '@/api/childEnglishApi';

export default {
  name: 'ReadingLearning',
  data() {
    return {
      currentTab: 'bookshelf',
      currentBook: null,
      readingMode: null, // 'accompany', 'follow', 'auto'
      currentPage: 0,
      currentSentenceIndex: -1,
      loading: false,
      followReadResult: null, // 当前显示的跟读结果
      followReadResults: [], // 所有单句跟读记录
      currentFollowReadResultIndex: -1, // 当前显示的跟读结果索引
      isAutoPlaying: false, // 是否正在自动播放
      autoPlayTimer: null, // 自动播放定时器
      autoPlaySentenceIndex: 0, // 自动播放当前句子索引
      speechSynthesis: null, // 语音合成对象
      isSpeaking: false, // 是否正在播放语音
      // 跟读相关
      isRecording: false, // 是否正在录音
      recognition: null, // 语音识别对象
      showFollowReadModal: false, // 显示跟读模态框
      currentFollowReadIndex: -1, // 当前跟读的句子索引
      recordingStartTime: null, // 录音开始时间
      isPageRecording: false, // 是否正在整页录音
      mediaRecorder: null, // MediaRecorder 对象
      audioChunks: [], // 录音数据块
      recordingStream: null, // 录音流
      playingAudioUrl: null, // 当前播放的音频URL
      recordedAudioUrl: null, // 当前录制的音频URL（单句）
      recordedPageAudioUrl: null, // 当前录制的音频URL（整页）
      showPageFollowReadModal: false, // 显示整页跟读模态框
      pageFollowReadResult: null, // 当前显示的整页跟读结果
      pageFollowReadResults: [], // 所有整页跟读记录
      currentPageFollowReadResultIndex: -1, // 当前显示的整页跟读结果索引
      pageRecognitionTranscript: '', // 整页跟读累积的识别文本
      recognitionTranscript: '', // 单句跟读累积的识别文本
      countdown: 3, // 单句跟读倒计时
      pageCountdown: 3, // 整页跟读倒计时
      countdownTimer: null, // 单句倒计时定时器
      pageCountdownTimer: null, // 整页倒计时定时器
      showReadingRecords: false, // 显示阅读记录
      showAccuracyDetails: false, // 显示跟读详情
      sentenceTranslations: {}, // 存储句子的翻译 { 'pageIndex-sentenceIndex': 'translation' }
      showingTranslations: {}, // 存储哪些句子正在显示翻译 { 'pageIndex-sentenceIndex': true }
      showPronunciationDetailsModal: false, // 显示发音详情模态框
      currentPronunciationDetails: null, // 当前显示的发音详情
      // 使用渐变背景作为默认封面，每个绘本会有不同的颜色
      defaultCover: '',
      defaultImage: '',
      books: [],
      // 默认示例数据（当后端没有数据时使用）
      defaultBooks: [
        {
          id: 1,
          title: 'The Very Hungry Caterpillar',
          cover: '',
          difficulty: 'easy',
          progress: 100,
          pages: [
            {
              image: 'https://picsum.photos/seed/caterpillar-page1/400/500',
              sentences: [
                { text: 'In the light of the moon, a little egg lay on a leaf.', audio: '' },
                { text: 'One Sunday morning, the warm sun came up.', audio: '' },
                { text: 'Pop! Out of the egg came a tiny and very hungry caterpillar.', audio: '' }
              ],
              parentTip: '可以问孩子："毛毛虫吃了什么？"引导孩子观察图片中的食物。'
            },
            {
              image: 'https://picsum.photos/seed/caterpillar-page2/400/500',
              sentences: [
                { text: 'He started to look for some food.', audio: '' },
                { text: 'On Monday, he ate through one apple.', audio: '' },
                { text: 'But he was still hungry.', audio: '' }
              ],
              parentTip: '让孩子数一数毛毛虫吃了多少个苹果，练习数字。'
            }
          ]
        },
        {
          id: 2,
          title: 'Brown Bear, Brown Bear',
          cover: '',
          difficulty: 'easy',
          progress: 60,
          pages: [
            {
              image: 'https://picsum.photos/seed/brownbear-page1/400/500',
              sentences: [
                { text: 'Brown bear, brown bear, what do you see?', audio: '' },
                { text: 'I see a red bird looking at me.', audio: '' }
              ],
              parentTip: '可以教孩子认识颜色，指着图片问："这是什么颜色？"'
            },
            {
              image: 'https://picsum.photos/seed/brownbear-page2/400/500',
              sentences: [
                { text: 'Red bird, red bird, what do you see?', audio: '' },
                { text: 'I see a yellow duck looking at me.', audio: '' }
              ],
              parentTip: '让孩子模仿动物的叫声，增加趣味性。'
            }
          ]
        },
        {
          id: 3,
          title: 'Where the Wild Things Are',
          cover: '',
          difficulty: 'medium',
          progress: 0,
          pages: [
            {
              image: 'https://picsum.photos/seed/wildthings-page1/400/500',
              sentences: [
                { text: 'The night Max wore his wolf suit and made mischief of one kind and another.', audio: '' },
                { text: 'His mother called him "WILD THING!"', audio: '' }
              ],
              parentTip: '可以问孩子："Max为什么被妈妈叫野东西？"讨论行为规范。'
            }
          ]
        },
        {
          id: 4,
          title: 'Goodnight Moon',
          cover: '',
          difficulty: 'easy',
          progress: 30,
          pages: [
            {
              image: 'https://picsum.photos/seed/moon-page1/400/500',
              sentences: [
                { text: 'In the great green room, there was a telephone.', audio: '' },
                { text: 'And a red balloon, and a picture of a cow jumping over the moon.', audio: '' }
              ],
              parentTip: '睡前故事，可以让孩子指认房间里的物品。'
            }
          ]
        },
        {
          id: 5,
          title: 'The Cat in the Hat',
          cover: '',
          difficulty: 'medium',
          progress: 0,
          pages: [
            {
              image: 'https://picsum.photos/seed/catinthehat-page1/400/500',
              sentences: [
                { text: 'The sun did not shine. It was too wet to play.', audio: '' },
                { text: 'So we sat in the house all that cold, cold, wet day.', audio: '' }
              ],
              parentTip: '可以问孩子："下雨天可以做什么？"引导思考。'
            }
          ]
        },
        {
          id: 6,
          title: 'Green Eggs and Ham',
          cover: '',
          difficulty: 'easy',
          progress: 0,
          pages: [
            {
              image: 'https://picsum.photos/seed/greeneggs-page1/400/500',
              sentences: [
                { text: 'I am Sam. Sam I am.', audio: '' },
                { text: 'I do not like green eggs and ham.', audio: '' }
              ],
              parentTip: '可以讨论食物的喜好，问孩子："你喜欢吃什么？"'
            }
          ]
        }
      ],
      monthlyReadCount: 8,
      averageAccuracy: 85,
      readingRecords: [
        {
          id: 1,
          bookTitle: 'The Very Hungry Caterpillar',
          bookCover: '',
          readDate: '2024-01-15',
          scores: [90, 95, 88]
        },
        {
          id: 2,
          bookTitle: 'Brown Bear, Brown Bear',
          bookCover: '',
          readDate: '2024-01-14',
          scores: [85, 90]
        },
        {
          id: 3,
          bookTitle: 'Goodnight Moon',
          bookCover: '',
          readDate: '2024-01-13',
          scores: [80]
        }
      ]
    };
  },
  computed: {
    // 按难度分组绘本
    booksByDifficulty() {
      const grouped = {
        easy: [],
        medium: [],
        hard: []
      };
      
      this.books.forEach(book => {
        const difficulty = book.difficulty || 'easy';
        if (difficulty === 'easy') {
          grouped.easy.push(book);
        } else if (difficulty === 'medium') {
          grouped.medium.push(book);
        } else if (difficulty === 'hard') {
          grouped.hard.push(book);
        } else {
          // 未知难度默认归为简单
          grouped.easy.push(book);
        }
      });
      
      return grouped;
    }
  },
  mounted() {
    this.loadBooks();
    this.initSpeechSynthesis();
    this.initSpeechRecognition();
  },
  methods: {
    async loadBooks() {
      this.loading = true;
      try {
        const response = await childEnglishApi.getRecommendedBooks();
        if (response && response.data && response.data.books) {
          // 转换后端数据格式为前端需要的格式
          this.books = response.data.books.map(book => ({
            id: book.id,
            title: book.title,
            cover: book.cover || '',
            difficulty: book.difficulty || 'easy',
            progress: book.progress || 0,
            pages: book.pages || []
          }));
        } else {
          // 如果后端没有数据，使用默认数据
          this.books = this.defaultBooks;
        }
      } catch (error) {
        console.error('加载推荐绘本失败:', error);
        // 出错时使用默认数据
        this.books = this.defaultBooks;
      } finally {
        this.loading = false;
      }
    },
    async openBook(book) {
      try {
        // 如果绘本没有pages数据，尝试从API获取详情
        if (!book.pages || book.pages.length === 0) {
          const response = await childEnglishApi.getBookDetail(book.id);
          if (response && response.data && response.data.book) {
            const bookDetail = response.data.book;
            this.currentBook = {
              ...book,
              pages: bookDetail.pages || [],
              author: bookDetail.author,
              description: bookDetail.description
            };
          } else {
            this.currentBook = { ...book };
          }
        } else {
          this.currentBook = { ...book };
        }
      } catch (error) {
        console.error('获取绘本详情失败:', error);
        this.currentBook = { ...book };
      }
      
      this.currentPage = 0;
      this.currentSentenceIndex = -1;
      this.readingMode = 'accompany'; // 默认进入伴读模式
      this.isAutoPlaying = false;
      this.stopAutoPlay(); // 确保停止之前的自动播放
      this.currentTab = 'reader';
      
      // 加载当前页面的录音记录
      this.loadPageRecordingResults();
    },
    startReading(mode) {
      this.readingMode = mode;
      this.stopAutoPlay(); // 切换模式时停止自动播放
    },
    // 切换自动播放
    toggleAutoPlay() {
      if (this.isAutoPlaying) {
        this.stopAutoPlay();
      } else {
        this.startAutoPlay();
      }
    },
    // 开始自动播放
    startAutoPlay() {
      if (!this.currentBook || !this.currentBook.pages || this.currentBook.pages.length === 0) {
        return;
      }
      
      this.isAutoPlaying = true;
      this.autoPlaySentenceIndex = 0;
      
      // 开始播放第一句
      this.playNextSentence();
    },
    // 播放下一句（用于自动播放）
    playNextSentence() {
      if (!this.isAutoPlaying) {
        return; // 如果已停止，不再继续
      }
      
      if (this.autoPlaySentenceIndex < this.currentBook.pages[this.currentPage].sentences.length) {
        // 播放当前句子，播放完成后会在 onAudioEnded 中调用此方法继续下一句
        this.playSentence(this.autoPlaySentenceIndex);
        this.autoPlaySentenceIndex++;
      } else {
        // 当前页播放完毕，停止自动播放
        this.stopAutoPlay();
      }
    },
    // 停止自动播放
    stopAutoPlay() {
      this.isAutoPlaying = false;
      if (this.autoPlayTimer) {
        clearTimeout(this.autoPlayTimer);
        this.autoPlayTimer = null;
      }
      this.autoPlaySentenceIndex = 0;
      this.currentSentenceIndex = -1;
    },
    goBack() {
      // 如果正在阅读器中，返回书架
      if (this.currentTab === 'reader') {
        this.exitReader();
      } else {
        // 否则返回首页
        this.$router.push('/');
      }
    },
    exitReader() {
      this.stopSpeaking(); // 停止当前播放
      this.stopAutoPlay(); // 退出阅读器时停止自动播放
      this.closeFollowReadModal(); // 关闭单句跟读模态框
      this.closePageFollowReadModal(); // 关闭整页跟读模态框
      this.currentTab = 'bookshelf';
      this.currentBook = null;
      this.readingMode = null;
      this.currentPage = 0;
      this.currentSentenceIndex = -1;
      this.followReadResult = null;
      this.followReadResults = [];
      this.currentFollowReadResultIndex = -1;
      this.pageFollowReadResult = null;
      this.pageFollowReadResults = [];
      this.currentPageFollowReadResultIndex = -1;
    },
    // 初始化语音合成
    initSpeechSynthesis() {
      if ('speechSynthesis' in window) {
        this.speechSynthesis = window.speechSynthesis;
      } else {
        console.warn('浏览器不支持语音合成功能');
      }
    },
    // 处理句子点击事件（避免与按钮点击冲突）
    handleSentenceClick(index, event) {
      // 如果点击的是按钮区域，不播放音频
      if (event.target.closest('.sentence-actions')) {
        return;
      }
      this.playSentence(index);
    },
    // 播放句子（使用Web Speech API）
    playSentence(index) {
      // 如果正在播放，先停止
      if (this.isSpeaking) {
        this.stopSpeaking();
      }
      
      this.currentSentenceIndex = index;
      const sentence = this.currentBook.pages[this.currentPage].sentences[index];
      
      // 优先使用音频文件
      if (sentence.audio && this.$refs.audioPlayer) {
        this.$refs.audioPlayer.src = sentence.audio;
        this.$refs.audioPlayer.play().catch(err => {
          console.error('音频播放失败:', err);
          // 如果音频播放失败，使用文本转语音
          this.speakText(sentence.text);
        });
      } else {
        // 使用文本转语音
        this.speakText(sentence.text);
      }
    },
    // 使用文本转语音播放
    speakText(text) {
      if (!this.speechSynthesis) {
        console.warn('语音合成不可用');
        // 模拟播放
        setTimeout(() => {
          this.onAudioEnded();
        }, 2000);
        return;
      }
      
      // 停止之前的语音
      this.speechSynthesis.cancel();
      
      const utterance = new SpeechSynthesisUtterance(text);
      utterance.lang = 'en-US'; // 设置为英语
      utterance.rate = 0.9; // 语速稍慢，适合儿童
      utterance.pitch = 1.0; // 音调
      utterance.volume = 1.0; // 音量
      
      utterance.onstart = () => {
        this.isSpeaking = true;
      };
      
      utterance.onend = () => {
        this.isSpeaking = false;
        this.onAudioEnded();
      };
      
      utterance.onerror = (error) => {
        console.error('语音合成错误:', error);
        this.isSpeaking = false;
        this.onAudioEnded();
      };
      
      this.speechSynthesis.speak(utterance);
    },
    // 播放单词的正确读音
    playWord(word) {
      if (!word) {
        return;
      }
      
      if (!this.speechSynthesis) {
        console.warn('语音合成不可用');
        return;
      }
      
      // 停止之前的语音
      this.speechSynthesis.cancel();
      
      const utterance = new SpeechSynthesisUtterance(word);
      utterance.lang = 'en-US'; // 设置为英语
      utterance.rate = 0.8; // 语速稍慢，便于学习
      utterance.pitch = 1.0; // 音调
      utterance.volume = 1.0; // 音量
      
      // 单词播放不需要触发 onAudioEnded
      this.speechSynthesis.speak(utterance);
    },
    // 停止语音播放
    stopSpeaking() {
      if (this.speechSynthesis) {
        this.speechSynthesis.cancel();
      }
      if (this.$refs.audioPlayer) {
        this.$refs.audioPlayer.pause();
        this.$refs.audioPlayer.currentTime = 0;
      }
      this.isSpeaking = false;
    },
    // 初始化语音识别
    initSpeechRecognition() {
      if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {
        const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
        this.recognition = new SpeechRecognition();
        this.recognition.lang = 'en-US'; // 设置为英语识别
        this.recognition.continuous = false; // 不连续识别
        this.recognition.interimResults = false; // 不返回中间结果
        
        this.recognition.onstart = () => {
          // 根据是整页还是单句设置不同的状态
          if (this.isPageRecording) {
            this.isPageRecording = true;
          } else {
            this.isRecording = true;
          }
        };
        
        this.recognition.onresult = (event) => {
          // 连续模式下，累积所有识别结果
          let finalTranscript = '';
          for (let i = 0; i < event.results.length; i++) {
            finalTranscript += event.results[i][0].transcript + ' ';
          }
          
          // 判断是整页跟读还是单句跟读
          if (this.isPageRecording) {
            this.pageRecognitionTranscript = finalTranscript.trim();
          } else {
            this.recognitionTranscript = finalTranscript.trim();
          }
        };
        
        this.recognition.onerror = (event) => {
          console.error('语音识别错误:', event.error);
          // 判断是整页跟读还是单句跟读
          if (this.isPageRecording) {
            this.handlePageRecognitionError(event.error);
          } else {
            this.handleRecognitionError(event.error);
          }
        };
        
        this.recognition.onend = () => {
          // 在录音结束时处理累积的识别结果
          // 先停止 MediaRecorder（如果还在运行）
          if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {
            console.log('recognition.onend: 停止 MediaRecorder');
            this.mediaRecorder.stop();
            // 等待一小段时间让 onstop 事件触发
            setTimeout(() => {
              this.processRecognitionResult();
            }, 100);
          } else {
            // MediaRecorder 已经停止，直接处理结果
            this.processRecognitionResult();
          }
          
          this.isRecording = false;
          this.isPageRecording = false;
        };
      } else {
        console.warn('浏览器不支持语音识别功能');
      }
    },
    // 开始跟读
    startFollowRead(index) {
      if (!this.recognition) {
        alert('您的浏览器不支持语音识别功能，请使用Chrome或Edge浏览器。');
        return;
      }
      
      this.currentSentenceIndex = index;
      this.currentFollowReadIndex = index;
      const sentence = this.currentBook.pages[this.currentPage].sentences[index];
      
      // 显示跟读模态框
      this.showFollowReadModal = true;
      this.followReadResult = null;
      this.countdown = 3;
      
      // 清除之前的倒计时
      if (this.countdownTimer) {
        clearInterval(this.countdownTimer);
        this.countdownTimer = null;
      }
      
      // 立即显示倒计时3，然后每秒更新
      // 第一次更新在1秒后（显示2），第二次在2秒后（显示1），第三次在3秒后（开始录音）
      this.countdownTimer = setInterval(() => {
        this.countdown--;
        if (this.countdown <= 0) {
          clearInterval(this.countdownTimer);
          this.countdownTimer = null;
          this.countdown = 0;
          if (this.showFollowReadModal) {
            this.startRecording(sentence.text);
          }
        }
      }, 1000);
    },
    // 开始录音
    async startRecording(expectedText) {
      if (!this.recognition || this.isRecording) {
        return;
      }
      
      this.recordingStartTime = Date.now();
      this.expectedText = expectedText.toLowerCase(); // 保存期望的文本用于比较
      this.recognitionTranscript = ''; // 清空之前的识别结果
      this.audioChunks = []; // 清空之前的音频数据
      this.recordedAudioUrl = null; // 清空之前的录音URL
      
      // 启动音频录制
      try {
        const stream = await navigator.mediaDevices.getUserMedia({ 
          audio: {
            echoCancellation: true,
            noiseSuppression: true,
            autoGainControl: true
          }
        });
        
        this.recordingStream = stream;
        const mimeType = this.getSupportedMimeType();
        this.mediaRecorder = new MediaRecorder(stream, { mimeType });
        
        this.mediaRecorder.ondataavailable = (event) => {
          if (event.data.size > 0) {
            this.audioChunks.push(event.data);
          }
        };
        
        this.mediaRecorder.onstop = () => {
          // 在停止时创建音频 Blob 和 URL
          console.log('MediaRecorder onstop 事件触发，音频块数量:', this.audioChunks.length);
          if (this.audioChunks.length > 0) {
            const audioBlob = new Blob(this.audioChunks, { 
              type: this.mediaRecorder.mimeType || 'audio/webm' 
            });
            // 单句录音保存到 recordedAudioUrl
            this.recordedAudioUrl = URL.createObjectURL(audioBlob);
            console.log('单句音频录制完成，大小:', audioBlob.size, 'bytes', 'URL:', this.recordedAudioUrl);
          } else {
            console.warn('音频块为空，无法创建音频URL');
          }
          
          // 停止录音流
          if (this.recordingStream) {
            this.recordingStream.getTracks().forEach(track => track.stop());
            this.recordingStream = null;
          }
        };
        
        this.mediaRecorder.start();
      } catch (error) {
        console.warn('音频录制启动失败，继续使用语音识别:', error);
        // 如果音频录制失败，仍然继续使用语音识别
      }
      
      // 单句跟读也使用连续模式，避免因静音而提前结束
      this.recognition.continuous = true;
      
      try {
        this.recognition.start();
      } catch (error) {
        console.error('启动语音识别失败:', error);
        this.handleRecognitionError('启动失败');
      }
    },
    // 停止录音
    stopRecording() {
      if (this.recognition && this.isRecording) {
        this.recognition.stop();
      }
      
      // 停止音频录制（先停止 MediaRecorder，等待 onstop 事件）
      if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {
        console.log('停止 MediaRecorder，当前状态:', this.mediaRecorder.state, '音频块数量:', this.audioChunks.length);
        this.mediaRecorder.stop();
      }
      
      // 注意：不要立即停止录音流，让 MediaRecorder 的 onstop 事件先完成
      // 录音流会在 onstop 事件中或稍后停止
    },
    // 处理识别结果（内部方法，由 processRecognitionResult 调用）
    processRecognitionResult() {
      if (this.isPageRecording && this.pageRecognitionTranscript) {
        this.handlePageRecognitionResult(this.pageRecognitionTranscript);
        this.pageRecognitionTranscript = ''; // 清空累积的文本
      } else if (this.recognitionTranscript) {
        this.handleRecognitionResult(this.recognitionTranscript);
        this.recognitionTranscript = ''; // 清空累积的文本
      }
    },
    // 处理识别结果
    handleRecognitionResult(transcript) {
      const recognizedText = transcript.toLowerCase();
      const expectedText = this.expectedText.toLowerCase();
      
      // 计算相似度（简单的字符串匹配）
      const similarity = this.calculateSimilarity(recognizedText, expectedText);
      const score = Math.round(similarity * 100);
      
      // 单词级别的发音评测
      const wordScores = this.evaluateWordPronunciation(expectedText, recognizedText);
      
      // 生成反馈
      let feedback = '';
      const problemWords = wordScores.filter(w => w.score < 70).map(w => w.word);
      if (score >= 90) {
        feedback = '发音非常标准，继续保持！';
      } else if (score >= 80) {
        if (problemWords.length > 0) {
          feedback = `发音不错，但 "${problemWords.join('", "')}" 这几个单词需要多练习。`;
        } else {
          feedback = '发音不错，可以再注意一下语调。';
        }
      } else if (score >= 60) {
        if (problemWords.length > 0) {
          feedback = `发音基本正确，但 "${problemWords.join('", "')}" 这几个单词需要多听几遍原音。`;
        } else {
          feedback = '发音基本正确，建议多听几遍原音。';
        }
      } else {
        if (problemWords.length > 0) {
          feedback = `发音需要多练习，特别是 "${problemWords.join('", "')}" 这几个单词，建议多听几遍原音并重新尝试。`;
        } else {
          feedback = '发音需要多练习，建议多听几遍原音并重新尝试。';
        }
      }
      
      // 等待一小段时间确保 MediaRecorder 的 onstop 事件已触发
      // 如果还没有音频URL，等待一下再检查
      let audioUrl = this.recordedAudioUrl;
      console.log('处理识别结果，当前 audioUrl:', audioUrl, 'audioChunks 长度:', this.audioChunks.length);
      
      if (!audioUrl && this.mediaRecorder && this.audioChunks.length > 0) {
        // 如果 onstop 还没触发，手动创建 Blob
        console.log('手动创建音频 Blob');
        const audioBlob = new Blob(this.audioChunks, { 
          type: this.mediaRecorder.mimeType || 'audio/webm' 
        });
        audioUrl = URL.createObjectURL(audioBlob);
        this.recordedAudioUrl = audioUrl;
        console.log('手动创建音频URL:', audioUrl);
      }
      
      const result = {
        id: Date.now(), // 使用时间戳作为唯一ID
        timestamp: new Date().toLocaleString('zh-CN'),
        sentenceIndex: this.currentFollowReadIndex,
        score: score,
        feedback: feedback,
        recognizedText: transcript,
        expectedText: this.expectedText,
        wordScores: wordScores,
        audioUrl: audioUrl // 用户录音的URL
      };
      
      console.log('保存结果，audioUrl:', result.audioUrl);
      
      // 添加到记录数组
      this.followReadResults.push(result);
      // 设置为当前显示的结果（最新的一条）
      this.currentFollowReadResultIndex = this.followReadResults.length - 1;
      this.followReadResult = result;
      
      // 保存到 localStorage
      this.saveFollowReadResults();
      
      // 不再自动关闭，让用户手动关闭以便仔细查看结果
    },
    // 单词级别的发音评测
    evaluateWordPronunciation(expectedText, recognizedText) {
      // 将文本分割成单词（移除标点符号）
      const expectedWords = expectedText.replace(/[^\w\s]/g, '').toLowerCase().split(/\s+/).filter(w => w.length > 0);
      const recognizedWords = recognizedText.replace(/[^\w\s]/g, '').toLowerCase().split(/\s+/).filter(w => w.length > 0);
      
      const wordScores = [];
      
      // 为每个期望的单词计算匹配度
      expectedWords.forEach((expectedWord, index) => {
        let bestMatch = null;
        let bestScore = 0;
        
        // 在识别的单词中寻找最佳匹配（考虑位置偏移）
        const searchStart = Math.max(0, index - 2);
        const searchEnd = Math.min(recognizedWords.length, index + 3);
        
        for (let i = searchStart; i < searchEnd; i++) {
          if (i < recognizedWords.length) {
            const recognizedWord = recognizedWords[i];
            // 计算单词相似度
            const similarity = this.calculateWordSimilarity(expectedWord, recognizedWord);
            
            // 考虑位置距离的权重
            const positionWeight = 1 - Math.abs(i - index) * 0.1;
            const weightedScore = similarity * positionWeight;
            
            if (weightedScore > bestScore) {
              bestScore = weightedScore;
              bestMatch = recognizedWord;
            }
          }
        }
        
        // 如果完全匹配，给高分
        if (bestMatch === expectedWord) {
          bestScore = 1.0;
        }
        
        // 计算最终分数（0-100）
        const finalScore = Math.round(bestScore * 100);
        
        wordScores.push({
          word: expectedWord,
          recognized: bestMatch || '(未识别)',
          score: finalScore,
          isCorrect: finalScore >= 80
        });
      });
      
      return wordScores;
    },
    // 计算单词相似度
    calculateWordSimilarity(word1, word2) {
      if (word1 === word2) {
        return 1.0;
      }
      
      // 使用Levenshtein距离计算相似度
      const distance = this.levenshteinDistance(word1, word2);
      const maxLength = Math.max(word1.length, word2.length);
      
      if (maxLength === 0) {
        return 1.0;
      }
      
      // 相似度 = 1 - (距离 / 最大长度)
      const similarity = 1 - (distance / maxLength);
      
      // 如果单词长度差异很大，降低相似度
      const lengthRatio = Math.min(word1.length, word2.length) / Math.max(word1.length, word2.length);
      return similarity * lengthRatio;
    },
    // 获取单词评分样式类
    getWordScoreClass(score) {
      if (score >= 90) {
        return 'word-score-excellent';
      } else if (score >= 80) {
        return 'word-score-good';
      } else if (score >= 70) {
        return 'word-score-fair';
      } else {
        return 'word-score-poor';
      }
    },
    // 获取单词提示文本
    getWordTitle(wordScore) {
      if (wordScore.score < 80) {
        return `点击播放 "${wordScore.word}" 的正确读音 (准确率: ${wordScore.score}%)`;
      } else {
        return `${wordScore.word}: ${wordScore.score}%`;
      }
    },
    // 处理单词点击事件
    handleWordClick(wordScore) {
      if (wordScore.score < 80) {
        this.playWord(wordScore.word);
      }
    },
    // 检查是否正在显示翻译
    isShowingTranslation(pageIndex, sentenceIndex) {
      const key = `${pageIndex}-${sentenceIndex}`;
      return !!this.showingTranslations[key];
    },
    // 切换翻译显示
    async toggleTranslation(pageIndex, sentenceIndex, sentenceText, event) {
      // 阻止事件冒泡，防止触发播放音频
      if (event) {
        event.stopPropagation();
        event.preventDefault();
      }
      
      const key = `${pageIndex}-${sentenceIndex}`;
      const isCurrentlyShowing = !!this.showingTranslations[key];
      
      // Vue 3 直接赋值即可，响应式系统会自动处理
      if (isCurrentlyShowing) {
        // 隐藏翻译
        this.showingTranslations[key] = false;
      } else {
        // 显示翻译
        this.showingTranslations[key] = true;
        
        // 如果还没有翻译，获取翻译
        if (!this.sentenceTranslations[key]) {
          // 先显示加载提示
          this.sentenceTranslations[key] = '正在加载翻译...';
          
          try {
            const translation = await this.getTranslationText(sentenceText);
            this.sentenceTranslations[key] = translation;
          } catch (error) {
            console.error('获取翻译失败:', error);
            this.sentenceTranslations[key] = '翻译暂时不可用，请稍后再试';
          }
        }
      }
    },
    // 获取翻译文本
    getTranslation(pageIndex, sentenceIndex, sentenceText) {
      const key = `${pageIndex}-${sentenceIndex}`;
      // 只有在显示翻译时才返回翻译文本
      if (this.showingTranslations[key]) {
        return this.sentenceTranslations[key] || '正在加载翻译...';
      }
      return '';
    },
    // 获取翻译文本（从字典或API）
    async getTranslationText(englishText) {
      // 首先检查预定义翻译字典
      const predefinedTranslation = this.getPredefinedTranslation(englishText);
      if (predefinedTranslation) {
        return predefinedTranslation;
      }
      
      // 如果没有预定义翻译，尝试使用在线翻译API
      try {
        // 这里可以使用免费的翻译API，比如 MyMemory Translation API
        const response = await fetch(
          `https://api.mymemory.translated.net/get?q=${encodeURIComponent(englishText)}&langpair=en|zh`
        );
        const data = await response.json();
        if (data.responseData && data.responseData.translatedText) {
          return data.responseData.translatedText;
        }
      } catch (error) {
        console.error('翻译API调用失败:', error);
      }
      
      // 如果都失败了，返回提示
      return '翻译暂时不可用，请稍后再试';
    },
    // 获取预定义翻译（针对常见绘本）
    getPredefinedTranslation(englishText) {
      const translationDict = {
        // The Very Hungry Caterpillar
        'In the light of the moon, a little egg lay on a leaf.': '在月光下，一片叶子上躺着一颗小蛋。',
        'One Sunday morning, the warm sun came up.': '一个星期天的早晨，温暖的太阳升起来了。',
        'Pop! Out of the egg came a tiny and very hungry caterpillar.': '砰！从蛋里爬出了一只很小很饿的毛毛虫。',
        'He started to look for some food.': '他开始寻找一些食物。',
        'On Monday, he ate through one apple.': '星期一，他吃了一个苹果。',
        'But he was still hungry.': '但他还是很饿。',
        
        // Brown Bear, Brown Bear
        'Brown bear, brown bear, what do you see?': '棕色的熊，棕色的熊，你看到了什么？',
        'I see a red bird looking at me.': '我看到一只红色的鸟在看着我。',
        'Red bird, red bird, what do you see?': '红色的鸟，红色的鸟，你看到了什么？',
        'I see a yellow duck looking at me.': '我看到一只黄色的鸭子在看着我。',
        
        // Where the Wild Things Are
        'The night Max wore his wolf suit and made mischief of one kind and another.': '那天晚上，马克斯穿着他的狼装，制造了各种各样的恶作剧。',
        'His mother called him "WILD THING!"': '他的妈妈叫他"野东西！"',
        
        // Goodnight Moon
        'In the great green room, there was a telephone.': '在绿色的大房间里，有一部电话。',
        'And a red balloon, and a picture of a cow jumping over the moon.': '还有一个红色的气球，和一幅奶牛跳过月亮的画。',
        
        // The Cat in the Hat
        'The sun did not shine. It was too wet to play.': '太阳没有出来。天气太湿了，不能玩。',
        'So we sat in the house all that cold, cold, wet day.': '所以我们整个寒冷、潮湿的雨天都坐在房子里。',
        
        // Green Eggs and Ham
        'I am Sam. Sam I am.': '我是山姆。山姆就是我。',
        'I do not like green eggs and ham.': '我不喜欢绿色的鸡蛋和火腿。'
      };
      
      return translationDict[englishText] || null;
    },
    // 获取单词翻译
    getWordMeaning(word) {
      if (!word) return '';
      
      // 清理单词（去除标点符号，转为小写）
      const cleanWord = word.toLowerCase().replace(/[.,!?;:]/g, '');
      
      // 单词翻译字典
      const wordDict = {
        // 常用单词
        'the': '这/那',
        'a': '一个',
        'an': '一个',
        'in': '在...里',
        'on': '在...上',
        'at': '在',
        'of': '...的',
        'to': '到/向',
        'for': '为了',
        'with': '和/用',
        'by': '通过',
        'from': '从',
        'up': '向上',
        'down': '向下',
        'out': '外面',
        'off': '离开',
        'over': '在...上方',
        'under': '在...下方',
        'into': '进入',
        'onto': '到...上',
        'upon': '在...上',
        
        // 常见名词
        'moon': '月亮',
        'sun': '太阳',
        'leaf': '叶子',
        'egg': '蛋',
        'caterpillar': '毛毛虫',
        'apple': '苹果',
        'food': '食物',
        'morning': '早晨',
        'night': '夜晚',
        'day': '天',
        'house': '房子',
        'room': '房间',
        'picture': '图片',
        'balloon': '气球',
        'cow': '奶牛',
        'bear': '熊',
        'bird': '鸟',
        'duck': '鸭子',
        'cat': '猫',
        'hat': '帽子',
        'ham': '火腿',
        'eggs': '鸡蛋',
        
        // 常见形容词
        'little': '小的',
        'tiny': '微小的',
        'hungry': '饥饿的',
        'warm': '温暖的',
        'cold': '冷的',
        'wet': '湿的',
        'green': '绿色的',
        'red': '红色的',
        'yellow': '黄色的',
        'brown': '棕色的',
        'wild': '野生的',
        'great': '伟大的',
        
        // 常见动词
        'lay': '躺/放置',
        'came': '来（过去式）',
        'started': '开始（过去式）',
        'look': '看',
        'see': '看见',
        'eat': '吃',
        'ate': '吃（过去式）',
        'like': '喜欢',
        'do': '做',
        'not': '不',
        'was': '是（过去式）',
        'were': '是（过去式）',
        'is': '是',
        'are': '是',
        'am': '是',
        'made': '制作（过去式）',
        'wore': '穿（过去式）',
        'called': '叫（过去式）',
        'sat': '坐（过去式）',
        'jumping': '跳跃',
        'looking': '看',
        
        // 常见代词
        'he': '他',
        'she': '她',
        'it': '它',
        'they': '他们',
        'we': '我们',
        'you': '你/你们',
        'i': '我',
        'me': '我（宾格）',
        'his': '他的',
        'her': '她的',
        'my': '我的',
        'your': '你的',
        'our': '我们的',
        'their': '他们的',
        
        // 常见疑问词
        'what': '什么',
        'where': '哪里',
        'when': '什么时候',
        'who': '谁',
        'why': '为什么',
        'how': '怎样',
        
        // 常见数词
        'one': '一',
        'two': '二',
        'three': '三',
        'four': '四',
        'five': '五',
        'six': '六',
        'seven': '七',
        'eight': '八',
        'nine': '九',
        'ten': '十',
        
        // 星期
        'sunday': '星期日',
        'monday': '星期一',
        'tuesday': '星期二',
        'wednesday': '星期三',
        'thursday': '星期四',
        'friday': '星期五',
        'saturday': '星期六',
        
        // 其他常见词
        'light': '光/灯',
        'lid': '盖子',
        'pop': '砰',
        'still': '仍然',
        'some': '一些',
        'all': '全部',
        'that': '那个',
        'this': '这个',
        'there': '那里',
        'telephone': '电话',
        'suit': '套装',
        'mischief': '恶作剧',
        'kind': '种类',
        'another': '另一个',
        'thing': '东西',
        'sam': '山姆（人名）',
        'max': '马克斯（人名）'
      };
      
      // 首先尝试直接匹配
      if (wordDict[cleanWord]) {
        return wordDict[cleanWord];
      }
      
      // 尝试匹配复数形式（去掉s）
      if (cleanWord.endsWith('s') && cleanWord.length > 1) {
        const singular = cleanWord.slice(0, -1);
        if (wordDict[singular]) {
          return wordDict[singular];
        }
      }
      
      // 尝试匹配过去式（去掉ed）
      if (cleanWord.endsWith('ed') && cleanWord.length > 2) {
        const base = cleanWord.slice(0, -2);
        if (wordDict[base]) {
          return wordDict[base];
        }
        // 尝试去掉d（如果以e结尾）
        const baseWithE = cleanWord.slice(0, -1);
        if (wordDict[baseWithE]) {
          return wordDict[baseWithE];
        }
      }
      
      // 尝试匹配进行时（去掉ing）
      if (cleanWord.endsWith('ing') && cleanWord.length > 3) {
        const base = cleanWord.slice(0, -3);
        if (wordDict[base]) {
          return wordDict[base];
        }
      }
      
      // 如果都找不到，返回空字符串（可以后续扩展为API调用）
      return '';
    },
    // 处理识别错误
    handleRecognitionError(error) {
      this.isRecording = false;
      this.recognitionTranscript = ''; // 清空累积的文本
      let errorMessage = '录音过程中出现错误，请重试。';
      
      if (error === 'no-speech') {
        errorMessage = '没有检测到语音，请重新尝试。';
      } else if (error === 'audio-capture') {
        errorMessage = '无法访问麦克风，请检查权限设置。';
      } else if (error === 'not-allowed') {
        errorMessage = '麦克风权限被拒绝，请在浏览器设置中允许麦克风访问。';
      }
      
      alert(errorMessage);
      this.showFollowReadModal = false;
    },
    // 计算文本相似度（简单的Levenshtein距离算法）
    calculateSimilarity(str1, str2) {
      // 移除标点符号和多余空格
      const clean1 = str1.replace(/[^\w\s]/g, '').replace(/\s+/g, ' ').trim();
      const clean2 = str2.replace(/[^\w\s]/g, '').replace(/\s+/g, ' ').trim();
      
      // 如果完全相同
      if (clean1 === clean2) {
        return 1.0;
      }
      
      // 计算Levenshtein距离
      const distance = this.levenshteinDistance(clean1, clean2);
      const maxLength = Math.max(clean1.length, clean2.length);
      
      // 相似度 = 1 - (距离 / 最大长度)
      return Math.max(0, 1 - distance / maxLength);
    },
    // Levenshtein距离算法
    levenshteinDistance(str1, str2) {
      const matrix = [];
      
      for (let i = 0; i <= str2.length; i++) {
        matrix[i] = [i];
      }
      
      for (let j = 0; j <= str1.length; j++) {
        matrix[0][j] = j;
      }
      
      for (let i = 1; i <= str2.length; i++) {
        for (let j = 1; j <= str1.length; j++) {
          if (str2.charAt(i - 1) === str1.charAt(j - 1)) {
            matrix[i][j] = matrix[i - 1][j - 1];
          } else {
            matrix[i][j] = Math.min(
              matrix[i - 1][j - 1] + 1,
              matrix[i][j - 1] + 1,
              matrix[i - 1][j] + 1
            );
          }
        }
      }
      
      return matrix[str2.length][str1.length];
    },
    // 获取当前页的完整文本
    getPageText() {
      if (!this.currentBook || !this.currentBook.pages || !this.currentBook.pages[this.currentPage]) {
        return '';
      }
      const sentences = this.currentBook.pages[this.currentPage].sentences || [];
      return sentences.map(s => s.text).join(' ');
    },
    // 关闭单句跟读模态框
    closeFollowReadModal() {
      this.stopRecording();
      if (this.countdownTimer) {
        clearInterval(this.countdownTimer);
        this.countdownTimer = null;
      }
      this.countdown = 3;
      this.recognitionTranscript = ''; // 清空累积的识别文本
      // 注意：不在这里清空 followReadResult 和 followReadResults，保留记录以便查看
      this.showFollowReadModal = false;
    },
    // 关闭整页跟读模态框
    closePageFollowReadModal() {
      this.stopPageRecording();
      if (this.pageCountdownTimer) {
        clearInterval(this.pageCountdownTimer);
        this.pageCountdownTimer = null;
      }
      this.pageCountdown = 3;
      this.pageRecognitionTranscript = ''; // 清空累积的识别文本
      this.showPageFollowReadModal = false;
    },
    // 开始整页跟读
    startPageFollowRead() {
      if (!this.recognition) {
        alert('您的浏览器不支持语音识别功能，请使用Chrome或Edge浏览器。');
        return;
      }
      
      if (!this.currentBook || !this.currentBook.pages || !this.currentBook.pages[this.currentPage]) {
        return;
      }
      
      // 获取当前页的所有句子文本
      const sentences = this.currentBook.pages[this.currentPage].sentences || [];
      if (sentences.length === 0) {
        alert('当前页没有内容可跟读。');
        return;
      }
      
      // 合并所有句子
      const pageText = sentences.map(s => s.text).join(' ');
      
      // 显示整页跟读模态框
      this.showPageFollowReadModal = true;
      this.pageFollowReadResult = null;
      this.pageFollowReadResults = [];
      this.currentPageFollowReadResultIndex = -1;
      this.followReadResult = null; // 清除当前显示的单句跟读结果
      this.followReadResults = []; // 清空所有单句跟读记录
      this.currentFollowReadResultIndex = -1;
      this.pageCountdown = 3;
      
      // 清除之前的倒计时
      if (this.pageCountdownTimer) {
        clearInterval(this.pageCountdownTimer);
        this.pageCountdownTimer = null;
      }
      
      // 立即显示倒计时3，然后每秒更新
      // 第一次更新在1秒后（显示2），第二次在2秒后（显示1），第三次在3秒后（开始录音）
      this.pageCountdownTimer = setInterval(() => {
        this.pageCountdown--;
        if (this.pageCountdown <= 0) {
          clearInterval(this.pageCountdownTimer);
          this.pageCountdownTimer = null;
          this.pageCountdown = 0;
          if (this.showPageFollowReadModal) {
            this.startPageRecording(pageText);
          }
        }
      }, 1000);
    },
    // 开始整页录音
    async startPageRecording(expectedText) {
      if (!this.recognition || this.isPageRecording) {
        return;
      }
      
      this.recordingStartTime = Date.now();
      this.expectedPageText = expectedText.toLowerCase(); // 保存期望的文本用于比较
      this.pageRecognitionTranscript = ''; // 清空之前的识别结果
      this.audioChunks = []; // 清空之前的音频数据
      this.recordedPageAudioUrl = null; // 清空之前的录音URL
      
      // 启动音频录制
      try {
        const stream = await navigator.mediaDevices.getUserMedia({ 
          audio: {
            echoCancellation: true,
            noiseSuppression: true,
            autoGainControl: true
          }
        });
        
        this.recordingStream = stream;
        const mimeType = this.getSupportedMimeType();
        this.mediaRecorder = new MediaRecorder(stream, { mimeType });
        
        this.mediaRecorder.ondataavailable = (event) => {
          if (event.data.size > 0) {
            this.audioChunks.push(event.data);
          }
        };
        
        this.mediaRecorder.onstop = () => {
          // 在停止时创建音频 Blob 和 URL
          console.log('MediaRecorder onstop 事件触发（整页），音频块数量:', this.audioChunks.length);
          if (this.audioChunks.length > 0) {
            const audioBlob = new Blob(this.audioChunks, { 
              type: this.mediaRecorder.mimeType || 'audio/webm' 
            });
            // 整页录音保存到 recordedPageAudioUrl
            this.recordedPageAudioUrl = URL.createObjectURL(audioBlob);
            console.log('整页音频录制完成，大小:', audioBlob.size, 'bytes', 'URL:', this.recordedPageAudioUrl);
          } else {
            console.warn('音频块为空，无法创建音频URL');
          }
          
          // 停止录音流
          if (this.recordingStream) {
            this.recordingStream.getTracks().forEach(track => track.stop());
            this.recordingStream = null;
          }
        };
        
        this.mediaRecorder.start();
      } catch (error) {
        console.warn('音频录制启动失败，继续使用语音识别:', error);
        // 如果音频录制失败，仍然继续使用语音识别
      }
      
      // 整页跟读使用连续模式，允许更长的录音时间
      this.recognition.continuous = true;
      
      try {
        this.recognition.start();
        this.isPageRecording = true;
      } catch (error) {
        console.error('启动语音识别失败:', error);
        this.handlePageRecognitionError('启动失败');
      }
    },
    // 停止整页录音
    stopPageRecording() {
      if (this.recognition && this.isPageRecording) {
        this.recognition.stop();
        // stop() 会触发 onend 事件，在那里处理识别结果
      }
      
      // 停止音频录制
      if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {
        this.mediaRecorder.stop();
      }
      
      // 停止录音流
      if (this.recordingStream) {
        this.recordingStream.getTracks().forEach(track => track.stop());
        this.recordingStream = null;
      }
      // 注意：不要在这里设置 isPageRecording = false，应该在 onend 中处理
    },
    // 处理整页识别结果
    handlePageRecognitionResult(transcript) {
      const recognizedText = transcript.toLowerCase();
      const expectedText = this.expectedPageText.toLowerCase();
      
      // 计算相似度
      const similarity = this.calculateSimilarity(recognizedText, expectedText);
      const score = Math.round(similarity * 100);
      
      // 单词级别的发音评测
      const wordScores = this.evaluateWordPronunciation(expectedText, recognizedText);
      
      // 生成反馈
      let feedback = '';
      const problemWords = wordScores.filter(w => w.score < 70).map(w => w.word);
      if (score >= 90) {
        feedback = '整页发音非常标准，继续保持！';
      } else if (score >= 80) {
        if (problemWords.length > 0) {
          feedback = `整页发音不错，但 "${problemWords.slice(0, 5).join('", "')}" 等单词需要多练习。`;
        } else {
          feedback = '整页发音不错，可以再注意一下语调和流畅度。';
        }
      } else if (score >= 60) {
        if (problemWords.length > 0) {
          feedback = `整页发音基本正确，但 "${problemWords.slice(0, 5).join('", "')}" 等单词需要多听几遍原音。`;
        } else {
          feedback = '整页发音基本正确，建议多听几遍原音，注意句子之间的连贯性。';
        }
      } else {
        if (problemWords.length > 0) {
          feedback = `整页发音需要多练习，特别是 "${problemWords.slice(0, 5).join('", "')}" 等单词，建议逐句练习后再尝试整页跟读。`;
        } else {
          feedback = '整页发音需要多练习，建议逐句练习后再尝试整页跟读。';
        }
      }
      
      // 等待一小段时间确保 MediaRecorder 的 onstop 事件已触发
      // 如果还没有音频URL，等待一下再检查
      let audioUrl = this.recordedPageAudioUrl;
      console.log('处理整页识别结果，当前 audioUrl:', audioUrl, 'audioChunks 长度:', this.audioChunks.length);
      
      if (!audioUrl && this.mediaRecorder && this.audioChunks.length > 0) {
        // 如果 onstop 还没触发，手动创建 Blob
        console.log('手动创建整页音频 Blob');
        const audioBlob = new Blob(this.audioChunks, { 
          type: this.mediaRecorder.mimeType || 'audio/webm' 
        });
        audioUrl = URL.createObjectURL(audioBlob);
        this.recordedPageAudioUrl = audioUrl;
        console.log('手动创建整页音频URL:', audioUrl);
      }
      
      const result = {
        id: Date.now(), // 使用时间戳作为唯一ID
        timestamp: new Date().toLocaleString('zh-CN'),
        score: score,
        feedback: feedback,
        recognizedText: transcript,
        expectedText: this.expectedPageText,
        wordScores: wordScores,
        audioUrl: audioUrl // 用户录音的URL
      };
      
      console.log('保存整页结果，audioUrl:', result.audioUrl);
      
      // 添加到记录数组
      this.pageFollowReadResults.push(result);
      // 设置为当前显示的结果（最新的一条）
      this.currentPageFollowReadResultIndex = this.pageFollowReadResults.length - 1;
      this.pageFollowReadResult = result;
      
      // 保存到 localStorage
      this.savePageFollowReadResults();
      
      this.isPageRecording = false;
      
      // 不再自动关闭，让用户手动关闭以便仔细查看结果
    },
    // 处理整页识别错误
    handlePageRecognitionError(error) {
      this.isPageRecording = false;
      this.pageRecognitionTranscript = ''; // 清空累积的文本
      let errorMessage = '录音过程中出现错误，请重试。';
      
      if (error === 'no-speech') {
        errorMessage = '没有检测到语音，请重新尝试。';
      } else if (error === 'audio-capture') {
        errorMessage = '无法访问麦克风，请检查权限设置。';
      } else if (error === 'not-allowed') {
        errorMessage = '麦克风权限被拒绝，请在浏览器设置中允许麦克风访问。';
      }
      
      alert(errorMessage);
      this.showPageFollowReadModal = false;
    },
    onAudioEnded() {
      this.currentSentenceIndex = -1;
      this.isSpeaking = false;
      
      // 如果正在自动播放，继续播放下一句
      if (this.isAutoPlaying) {
        // 使用 setTimeout 添加一个短暂的延迟，确保语音完全结束
        setTimeout(() => {
          if (this.isAutoPlaying) {
            this.playNextSentence();
          }
        }, 300); // 300ms 延迟，确保语音完全结束
      }
    },
    previousPage() {
      if (this.currentPage > 0) {
        this.stopSpeaking(); // 停止当前播放
        this.stopAutoPlay(); // 切换页面时停止自动播放
        this.closeFollowReadModal(); // 关闭跟读模态框
        this.currentPage--;
        this.currentSentenceIndex = -1;
        this.autoPlaySentenceIndex = 0; // 重置自动播放索引
        // 清空当前页的翻译显示状态（保留翻译数据以便复用）
        this.clearPageTranslationState(this.currentPage);
        // 加载新页面的录音记录
        this.loadPageRecordingResults();
      }
    },
    async nextPage() {
      if (this.currentPage < this.currentBook.pages.length - 1) {
        this.stopSpeaking(); // 停止当前播放
        this.stopAutoPlay(); // 切换页面时停止自动播放
        this.closeFollowReadModal(); // 关闭单句跟读模态框
        this.closePageFollowReadModal(); // 关闭整页跟读模态框
        // 清空当前页的翻译显示状态
        this.clearPageTranslationState(this.currentPage);
        this.currentPage++;
        this.currentSentenceIndex = -1;
        this.autoPlaySentenceIndex = 0; // 重置自动播放索引
        
        // 加载新页面的录音记录
        this.loadPageRecordingResults();
        
        // 更新进度
        const progress = Math.round(((this.currentPage + 1) / this.currentBook.pages.length) * 100);
        const book = this.books.find(b => b.id === this.currentBook.id);
        if (book) {
          book.progress = Math.max(book.progress, progress);
        }
        
        // 更新后端阅读进度
        try {
          await childEnglishApi.updateReadingProgress({
            bookId: this.currentBook.id,
            currentPage: this.currentPage + 1,
            totalPages: this.currentBook.pages.length
          });
        } catch (error) {
          console.error('更新阅读进度失败:', error);
        }
      }
    },
    goToPage(pageIndex) {
      this.stopSpeaking(); // 停止当前播放
      this.stopAutoPlay(); // 切换页面时停止自动播放
      this.closeFollowReadModal(); // 关闭单句跟读模态框
      this.closePageFollowReadModal(); // 关闭整页跟读模态框
      // 清空当前页的翻译显示状态
      this.clearPageTranslationState(this.currentPage);
      this.currentPage = pageIndex;
      this.currentSentenceIndex = -1;
      this.autoPlaySentenceIndex = 0; // 重置自动播放索引
      
      // 加载新页面的录音记录
      this.loadPageRecordingResults();
    },
    // 显示发音详情
    showPronunciationDetails(type) {
      console.log('showPronunciationDetails called', { type, pageResult: this.pageFollowReadResult, sentenceResult: this.followReadResult });
      if (type === 'page' && this.pageFollowReadResult) {
        this.currentPronunciationDetails = this.pageFollowReadResult;
        this.showPronunciationDetailsModal = true;
        console.log('Showing page pronunciation details', this.currentPronunciationDetails);
      } else if (type === 'sentence' && this.followReadResult) {
        this.currentPronunciationDetails = this.followReadResult;
        this.showPronunciationDetailsModal = true;
        console.log('Showing sentence pronunciation details', this.currentPronunciationDetails);
      } else {
        console.warn('No pronunciation result available', { type, pageResult: !!this.pageFollowReadResult, sentenceResult: !!this.followReadResult });
      }
    },
    // 关闭发音详情模态框
    closePronunciationDetailsModal() {
      // 停止播放录音
      if (this.playingAudioUrl && this.$refs.userRecordingPlayer) {
        this.$refs.userRecordingPlayer.pause();
        this.$refs.userRecordingPlayer.currentTime = 0;
        this.playingAudioUrl = null;
      }
      this.showPronunciationDetailsModal = false;
      this.currentPronunciationDetails = null;
    },
    // 播放用户录音
    playUserRecording(audioUrl) {
      if (!audioUrl) return;
      
      // 如果正在播放同一个音频，则停止
      if (this.playingAudioUrl === audioUrl && this.$refs.userRecordingPlayer) {
        this.$refs.userRecordingPlayer.pause();
        this.$refs.userRecordingPlayer.currentTime = 0;
        this.playingAudioUrl = null;
        return;
      }
      
      // 停止之前播放的音频
      if (this.$refs.userRecordingPlayer) {
        this.$refs.userRecordingPlayer.pause();
        this.$refs.userRecordingPlayer.currentTime = 0;
      }
      
      // 播放新的音频
      this.playingAudioUrl = audioUrl;
      this.$nextTick(() => {
        if (this.$refs.userRecordingPlayer) {
          this.$refs.userRecordingPlayer.src = audioUrl;
          this.$refs.userRecordingPlayer.play().catch(error => {
            console.error('播放录音失败:', error);
            this.playingAudioUrl = null;
          });
        }
      });
    },
    // 获取支持的MIME类型
    getSupportedMimeType() {
      const types = [
        'audio/webm;codecs=opus',
        'audio/webm',
        'audio/ogg;codecs=opus',
        'audio/mp4',
        'audio/wav'
      ];
      
      for (const type of types) {
        if (MediaRecorder.isTypeSupported(type)) {
          return type;
        }
      }
      return 'audio/webm'; // 默认
    },
    // 切换单句跟读记录
    switchFollowReadResult(direction, event) {
      if (event) {
        event.stopPropagation();
        event.preventDefault();
      }
      console.log('switchFollowReadResult called', { 
        direction, 
        currentIndex: this.currentFollowReadResultIndex, 
        total: this.followReadResults.length,
        results: this.followReadResults
      });
      const newIndex = this.currentFollowReadResultIndex + direction;
      console.log('New index:', newIndex, 'Valid range: 0 to', this.followReadResults.length - 1);
      if (newIndex >= 0 && newIndex < this.followReadResults.length) {
        // 先更新索引
        this.currentFollowReadResultIndex = newIndex;
        // 使用深拷贝确保创建新对象引用，触发响应式更新
        const result = this.followReadResults[newIndex];
        this.followReadResult = JSON.parse(JSON.stringify(result));
        console.log('Switched to result:', this.followReadResult, 'from index:', newIndex);
      } else {
        console.warn('Invalid index:', newIndex, 'Range: 0 to', this.followReadResults.length - 1);
      }
    },
    // 切换整页跟读记录
    switchPageResult(direction, event) {
      if (event) {
        event.stopPropagation();
        event.preventDefault();
      }
      console.log('switchPageResult called', { 
        direction, 
        currentIndex: this.currentPageFollowReadResultIndex, 
        total: this.pageFollowReadResults.length,
        results: this.pageFollowReadResults
      });
      const newIndex = this.currentPageFollowReadResultIndex + direction;
      console.log('New index:', newIndex, 'Valid range: 0 to', this.pageFollowReadResults.length - 1);
      if (newIndex >= 0 && newIndex < this.pageFollowReadResults.length) {
        // 先更新索引
        this.currentPageFollowReadResultIndex = newIndex;
        // 使用深拷贝确保创建新对象引用，触发响应式更新
        const result = this.pageFollowReadResults[newIndex];
        this.pageFollowReadResult = JSON.parse(JSON.stringify(result));
        console.log('Switched to result:', this.pageFollowReadResult, 'from index:', newIndex);
      } else {
        console.warn('Invalid index:', newIndex, 'Range: 0 to', this.pageFollowReadResults.length - 1);
      }
    },
    // 保存单句跟读记录到 localStorage
    saveFollowReadResults() {
      if (!this.currentBook || this.currentFollowReadIndex < 0) return;
      try {
        // 只保存当前句子的记录（从 followReadResults 中筛选出当前句子的记录）
        const currentSentenceResults = this.followReadResults.filter(
          r => r.sentenceIndex === this.currentFollowReadIndex
        );
        const key = `followRead_${this.currentBook.id}_${this.currentPage}_${this.currentFollowReadIndex}`;
        localStorage.setItem(key, JSON.stringify(currentSentenceResults));
        
        // 重新加载当前页面的所有记录以更新显示
        this.loadPageRecordingResults();
      } catch (error) {
        console.warn('保存单句跟读记录失败:', error);
      }
    },
    // 保存整页跟读记录到 localStorage
    savePageFollowReadResults() {
      if (!this.currentBook) return;
      try {
        const key = `pageFollowRead_${this.currentBook.id}_${this.currentPage}`;
        localStorage.setItem(key, JSON.stringify(this.pageFollowReadResults));
      } catch (error) {
        console.warn('保存整页跟读记录失败:', error);
      }
    },
    // 加载当前页面的所有录音记录
    loadPageRecordingResults() {
      if (!this.currentBook) return;
      
      // 加载当前页面的整页跟读记录
      try {
        const pageKey = `pageFollowRead_${this.currentBook.id}_${this.currentPage}`;
        const savedPageResults = localStorage.getItem(pageKey);
        if (savedPageResults) {
          this.pageFollowReadResults = JSON.parse(savedPageResults);
          if (this.pageFollowReadResults.length > 0) {
            // 显示最新的一条记录
            this.currentPageFollowReadResultIndex = this.pageFollowReadResults.length - 1;
            this.pageFollowReadResult = JSON.parse(JSON.stringify(this.pageFollowReadResults[this.currentPageFollowReadResultIndex]));
          } else {
            this.pageFollowReadResult = null;
            this.currentPageFollowReadResultIndex = -1;
          }
        } else {
          this.pageFollowReadResults = [];
          this.pageFollowReadResult = null;
          this.currentPageFollowReadResultIndex = -1;
        }
      } catch (error) {
        console.warn('加载整页跟读记录失败:', error);
        this.pageFollowReadResults = [];
        this.pageFollowReadResult = null;
        this.currentPageFollowReadResultIndex = -1;
      }
      
      // 加载当前页面的所有单句跟读记录（合并所有句子的记录）
      try {
        const allSentenceResults = [];
        if (this.currentBook.pages[this.currentPage] && this.currentBook.pages[this.currentPage].sentences) {
          this.currentBook.pages[this.currentPage].sentences.forEach((sentence, index) => {
            const sentenceKey = `followRead_${this.currentBook.id}_${this.currentPage}_${index}`;
            const savedSentenceResults = localStorage.getItem(sentenceKey);
            if (savedSentenceResults) {
              const results = JSON.parse(savedSentenceResults);
              allSentenceResults.push(...results);
            }
          });
        }
        
        // 按时间戳排序，最新的在前
        allSentenceResults.sort((a, b) => (b.id || 0) - (a.id || 0));
        
        if (allSentenceResults.length > 0) {
          this.followReadResults = allSentenceResults;
          // 显示最新的一条记录
          this.currentFollowReadResultIndex = 0;
          this.followReadResult = JSON.parse(JSON.stringify(allSentenceResults[0]));
        } else {
          this.followReadResults = [];
          this.followReadResult = null;
          this.currentFollowReadResultIndex = -1;
        }
      } catch (error) {
        console.warn('加载单句跟读记录失败:', error);
        this.followReadResults = [];
        this.followReadResult = null;
        this.currentFollowReadResultIndex = -1;
      }
    },
    // 清空指定页面的翻译显示状态
    clearPageTranslationState(pageIndex) {
      if (!this.currentBook || !this.currentBook.pages || !this.currentBook.pages[pageIndex]) {
        return;
      }
      const sentences = this.currentBook.pages[pageIndex].sentences || [];
      sentences.forEach((sentence, index) => {
        const key = `${pageIndex}-${index}`;
        this.showingTranslations[key] = false;
      });
    },
    handleImageError(event) {
      event.target.src = this.defaultImage;
    },
    getDifficultyText(difficulty) {
      const map = {
        easy: '简单',
        medium: '中等',
        hard: '困难'
      };
      return map[difficulty] || '简单';
    },
    getScoreClass(score) {
      if (score >= 90) return 'score-excellent';
      if (score >= 80) return 'score-good';
      if (score >= 70) return 'score-fair';
      return 'score-poor';
    },
    getScoreStatus(score) {
      if (score >= 90) return '优秀';
      if (score >= 80) return '良好';
      if (score >= 70) return '一般';
      return '需改进';
    },
    // 根据阅读记录获取对应的书籍
    getBookByTitle(bookTitle) {
      return this.books.find(book => book.title === bookTitle) || 
             this.defaultBooks.find(book => book.title === bookTitle);
    },
    // 获取阅读记录的书籍封面URL
    getRecordBookCover(record) {
      const book = this.getBookByTitle(record.bookTitle);
      if (book && book.cover && this.isValidImageUrl(book.cover)) {
        return book.cover;
      }
      return record.bookCover && this.isValidImageUrl(record.bookCover) ? record.bookCover : null;
    },
    // 获取阅读记录的书籍封面样式
    getRecordBookCoverStyle(record) {
      const coverUrl = this.getRecordBookCover(record);
      if (coverUrl) {
        return {
          backgroundImage: `url(${coverUrl})`,
          backgroundSize: 'cover',
          backgroundPosition: 'center'
        };
      }
      return {};
    },
    // 获取阅读记录的书籍渐变样式
    getRecordBookGradientStyle(record) {
      const book = this.getBookByTitle(record.bookTitle);
      if (book) {
        return this.getBookGradientStyle(book);
      }
      // 如果没有找到书籍，使用默认渐变
      const gradients = [
        'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
        'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
        'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)'
      ];
      const index = (record.id || 0) % gradients.length;
      return { background: gradients[index] };
    },
    // 获取阅读记录的书籍emoji
    getRecordBookEmoji(record) {
      const book = this.getBookByTitle(record.bookTitle);
      if (book) {
        return this.getBookEmoji(book);
      }
      const emojis = ['🐛', '🐻', '🌙', '🥚', '🐱', '👹', '🕷️', '🌳', '⚡', '🦁'];
      const index = (record.id || 0) % emojis.length;
      return emojis[index];
    },
    // 打开阅读记录
    openReadingRecords() {
      this.showReadingRecords = true;
      this.showAccuracyDetails = false; // 确保只显示阅读记录
    },
    // 打开跟读详情
    openAccuracyDetails() {
      this.showAccuracyDetails = true;
      this.showReadingRecords = false; // 确保只显示跟读详情
    },
    // 关闭详情
    closeDetails() {
      this.showReadingRecords = false;
      this.showAccuracyDetails = false;
    },
    // 获取绘本封面样式
    getBookCoverStyle(book) {
      if (book.cover && this.isValidImageUrl(book.cover)) {
        return {
          backgroundImage: `url(${book.cover})`,
          backgroundSize: 'cover',
          backgroundPosition: 'center'
        };
      }
      return {};
    },
    // 检查是否是有效的图片URL
    isValidImageUrl(url) {
      if (!url || url.trim() === '') return false;
      return url.startsWith('http://') || url.startsWith('https://') || url.startsWith('data:image');
    },
    // 为每本书生成不同的渐变背景
    getBookGradientStyle(book) {
      const gradients = [
        'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
        'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
        'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
        'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)',
        'linear-gradient(135deg, #fa709a 0%, #fee140 100%)',
        'linear-gradient(135deg, #30cfd0 0%, #330867 100%)',
        'linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)',
        'linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%)',
        'linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%)',
        'linear-gradient(135deg, #ff6e7f 0%, #bfe9ff 100%)'
      ];
      
      // 根据book.id选择不同的渐变
      const index = (book.id || 0) % gradients.length;
      return {
        background: gradients[index]
      };
    },
    // 为每本书选择不同的emoji图标
    getBookEmoji(book) {
      const emojis = ['🐛', '🐻', '🌙', '🥚', '🐱', '👹', '🕷️', '🌳', '⚡', '🦁'];
      const index = (book.id || 0) % emojis.length;
      return emojis[index];
    },
    // 获取页面图片（根据绘本标题和页码生成相应的图片）
    getPageImage(page) {
      if (page && page.image) {
        return page.image;
      }
      
      // 如果没有图片URL，根据当前绘本和页码生成相应的图片
      if (this.currentBook) {
        const bookTitle = this.currentBook.title || '';
        const pageNum = this.currentPage + 1;
        
        // 为不同绘本生成不同的图片
        if (bookTitle.includes('Caterpillar')) {
          return `https://picsum.photos/seed/caterpillar-page${pageNum}/400/500`;
        } else if (bookTitle.includes('Brown Bear')) {
          return `https://picsum.photos/seed/brownbear-page${pageNum}/400/500`;
        } else if (bookTitle.includes('Moon')) {
          return `https://picsum.photos/seed/moon-page${pageNum}/400/500`;
        } else if (bookTitle.includes('Green Eggs')) {
          return `https://picsum.photos/seed/greeneggs-page${pageNum}/400/500`;
        } else if (bookTitle.includes('Cat in the Hat')) {
          return `https://picsum.photos/seed/catinthehat-page${pageNum}/400/500`;
        } else if (bookTitle.includes('Wild Things')) {
          return `https://picsum.photos/seed/wildthings-page${pageNum}/400/500`;
        } else {
          // 默认根据bookId和页码生成
          const bookId = this.currentBook.id || 0;
          return `https://picsum.photos/seed/book${bookId}-page${pageNum}/400/500`;
        }
      }
      
      return this.defaultImage;
    },
    handleImageError(event) {
      // 如果图片加载失败，使用默认图片
      event.target.src = this.defaultImage;
    }
  }
};
</script>

<style scoped>
.reading-learning {
  min-height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  padding: 20px;
}

.page-header {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-bottom: 20px;
  max-width: 1200px;
  margin-left: auto;
  margin-right: auto;
}

.back-btn {
  padding: 10px 20px;
  background: rgba(255, 255, 255, 0.2);
  backdrop-filter: blur(10px);
  border: 2px solid rgba(255, 255, 255, 0.3);
  border-radius: 10px;
  color: white;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-weight: 500;
}

.back-btn:hover {
  background: rgba(255, 255, 255, 0.3);
  transform: translateX(-5px);
}

.page-header h1 {
  margin: 0;
  color: white;
  font-size: 28px;
  font-weight: 600;
}

/* 标签页导航 */
.tabs-nav {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
  max-width: 1200px;
  margin-left: auto;
  margin-right: auto;
}

.tab-btn {
  flex: 1;
  padding: 15px 20px;
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(10px);
  border: 2px solid rgba(255, 255, 255, 0.2);
  border-radius: 12px;
  color: white;
  font-size: 18px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
}

.tab-btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.25);
  transform: translateY(-2px);
}

.tab-btn.active {
  background: white;
  color: #667eea;
  border-color: white;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}

.tab-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* 书架界面 */
.bookshelf-container {
  max-width: 1200px;
  margin: 0 auto;
}

.bookshelf-card {
  background: white;
  border-radius: 24px;
  padding: 40px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
  position: relative;
  min-height: 600px;
}

.bookshelf-background {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 200px;
  background: linear-gradient(to bottom, #8b6914 0%, #6b5010 100%);
  border-radius: 0 0 24px 24px;
}

.shelf {
  position: absolute;
  left: 0;
  right: 0;
  height: 20px;
  background: #5a4209;
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
}

.shelf-1 {
  bottom: 60px;
}

.shelf-2 {
  bottom: 130px;
}

.shelf-3 {
  bottom: 200px;
}

/* 按难度分组的容器 */
.books-by-difficulty {
  position: relative;
  z-index: 1;
  padding-bottom: 220px;
}

.difficulty-section {
  margin-bottom: 40px;
}

.difficulty-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 15px 20px;
  border-radius: 12px;
  margin-bottom: 20px;
  font-size: 18px;
  font-weight: 600;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.difficulty-easy-header {
  background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%);
  color: #155724;
  border-left: 4px solid #28a745;
}

.difficulty-medium-header {
  background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%);
  color: #856404;
  border-left: 4px solid #ffc107;
}

.difficulty-hard-header {
  background: linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%);
  color: #721c24;
  border-left: 4px solid #dc3545;
}

.difficulty-icon {
  font-size: 24px;
}

.difficulty-title {
  flex: 1;
}

.difficulty-count {
  font-size: 14px;
  opacity: 0.8;
  font-weight: 500;
}

.books-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 30px;
  margin-bottom: 20px;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  text-align: center;
}

.empty-icon {
  font-size: 64px;
  margin-bottom: 20px;
  opacity: 0.5;
}

.empty-text {
  font-size: 18px;
  color: #7f8c8d;
  font-weight: 500;
}

.book-item {
  cursor: pointer;
  transition: all 0.3s ease;
}

.book-item:hover {
  transform: translateY(-10px);
}

.book-cover {
  position: relative;
  width: 100%;
  aspect-ratio: 3/4;
  margin-bottom: 10px;
  perspective: 1000px;
}

.cover-image {
  width: 100%;
  height: 100%;
  border-radius: 8px;
  background-size: cover;
  background-position: center;
  background-color: #f0f0f0;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
  transition: all 0.3s ease;
}

.book-item:hover .cover-image {
  transform: rotateY(-5deg) scale(1.05);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.3);
}

.cover-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 8px;
}

.cover-icon {
  font-size: 60px;
  opacity: 0.7;
}

.difficulty-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  padding: 4px 10px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.difficulty-easy {
  background: #d4edda;
  color: #155724;
}

.difficulty-medium {
  background: #fff3cd;
  color: #856404;
}

.difficulty-hard {
  background: #f8d7da;
  color: #721c24;
}

.progress-sticker {
  position: absolute;
  bottom: -8px;
  left: 50%;
  transform: translateX(-50%);
  padding: 6px 12px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  font-size: 12px;
  font-weight: 600;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  white-space: nowrap;
}

.progress-sticker.completed {
  background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
}

.book-title {
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  color: #2c3e50;
  margin-top: 5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.loading-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 400px;
  padding: 40px;
}

.loading-text {
  font-size: 18px;
  color: #667eea;
  font-weight: 600;
}

/* 阅读器界面 */
.reader-container {
  max-width: 1400px;
  margin: 0 auto;
}

/* 模式选择浮窗 */
.mode-selector-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  backdrop-filter: blur(5px);
}

.mode-selector-modal {
  background: white;
  border-radius: 24px;
  padding: 40px;
  max-width: 800px;
  width: 90%;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}

.mode-selector-modal h2 {
  text-align: center;
  font-size: 28px;
  color: #2c3e50;
  margin: 0 0 30px 0;
}

.mode-options {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.mode-btn {
  padding: 30px 20px;
  background: #f8f9fa;
  border: 3px solid #e0e0e0;
  border-radius: 16px;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
}

.mode-btn:hover {
  background: #e9ecef;
  border-color: #667eea;
  transform: translateY(-5px);
  box-shadow: 0 8px 20px rgba(102, 126, 234, 0.2);
}

.mode-icon {
  font-size: 48px;
}

.mode-title {
  font-size: 20px;
  font-weight: 600;
  color: #2c3e50;
}

.mode-desc {
  font-size: 14px;
  color: #7f8c8d;
  text-align: center;
}

.reader-card {
  background: white;
  border-radius: 24px;
  padding: 30px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}

.reader-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 30px;
  padding: 20px;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  border-radius: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.reader-title-section {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 15px;
}

.reader-title {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
  color: #2c3e50;
}

.reader-mode-badge {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 20px;
  color: white;
  font-size: 13px;
  font-weight: 500;
  box-shadow: 0 2px 6px rgba(102, 126, 234, 0.3);
}

.mode-badge-icon {
  font-size: 16px;
}

.mode-badge-text {
  font-size: 13px;
}

.reader-header-right {
  display: flex;
  align-items: center;
  gap: 15px;
}

.reader-progress {
  font-size: 14px;
  color: #7f8c8d;
  font-weight: 500;
  padding: 8px 16px;
  background: white;
  border-radius: 20px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* 头部自动播放按钮 */
.auto-play-btn-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  background: white;
  border: 2px solid #e0e0e0;
  border-radius: 20px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: 14px;
  font-weight: 600;
  color: #2c3e50;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.auto-play-btn-header:hover {
  border-color: #667eea;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
}

.auto-play-btn-header.active {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-color: #667eea;
  color: white;
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
}

.auto-play-icon-header {
  font-size: 16px;
}

.auto-play-text-header {
  font-size: 13px;
}

.reader-back-btn {
  padding: 10px 20px;
  background: white;
  border: 2px solid #e0e0e0;
  border-radius: 12px;
  color: #2c3e50;
  font-size: 15px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.reader-back-btn:hover {
  background: #f8f9fa;
  border-color: #667eea;
  transform: translateX(-3px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
}


.reader-content {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: 40px;
  margin-bottom: 30px;
  min-height: 500px;
  align-items: start;
}

.reader-image-section {
  display: flex;
  align-items: center;
  justify-content: center;
  position: sticky;
  top: 20px;
}

.book-image {
  width: 100%;
  max-width: 600px;
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 15px 40px rgba(0, 0, 0, 0.15);
  background: #f8f9fa;
  transition: transform 0.3s ease;
}

.book-image:hover {
  transform: scale(1.02);
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.2);
}

.book-image img {
  width: 100%;
  height: auto;
  display: block;
  object-fit: cover;
}

.reader-text-section {
  display: flex;
  flex-direction: column;
  padding: 20px 0;
}

.text-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.page-follow-read-section-right {
  display: flex;
  justify-content: center;
  margin-top: 20px;
  padding-top: 20px;
  border-top: 2px solid #e9ecef;
}

.page-follow-read-btn-right {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 28px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
  border-radius: 14px;
  color: white;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
  width: 100%;
  justify-content: center;
}

.page-follow-read-btn-right:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
}

.page-follow-read-btn-right:disabled {
  opacity: 0.7;
  cursor: not-allowed;
}

.page-follow-read-btn-right .btn-icon {
  font-size: 20px;
}

.page-follow-read-btn-right .btn-text {
  font-size: 16px;
}

.sentence-wrapper {
  margin-bottom: 12px;
}

.sentence-item {
  padding: 18px 20px;
  background: white;
  border: 2px solid #e9ecef;
  border-radius: 14px;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 15px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}

.sentence-item:hover {
  background: #f8f9fa;
  border-color: #667eea;
  transform: translateX(5px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);
}

.sentence-item.highlighted {
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.08) 0%, rgba(118, 75, 162, 0.08) 100%);
  border-color: #667eea;
  box-shadow: 0 6px 20px rgba(102, 126, 234, 0.25);
  transform: translateX(5px);
}

.sentence-text {
  flex: 1;
  font-size: 19px;
  line-height: 1.8;
  color: #2c3e50;
  font-weight: 500;
  letter-spacing: 0.3px;
}

.sentence-translation {
  width: 100%;
  margin-top: 10px;
  padding: 12px 16px;
  background: linear-gradient(135deg, #f0f7ff 0%, #e8f4fd 100%);
  border-left: 4px solid #4a90e2;
  border-radius: 8px;
  font-size: 15px;
  line-height: 1.7;
  color: #2c3e50;
  font-weight: 400;
  box-shadow: 0 2px 8px rgba(74, 144, 226, 0.1);
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
}

.translation-label {
  font-weight: 600;
  color: #4a90e2;
  margin-right: 8px;
}

.sentence-actions {
  display: flex;
  gap: 10px;
}

.action-btn {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  font-size: 18px;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.play-btn {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
}

.play-btn:hover {
  transform: scale(1.15);
  box-shadow: 0 6px 20px rgba(102, 126, 234, 0.5);
}

.follow-btn {
  background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
  color: white;
}

.follow-btn:hover {
  transform: scale(1.15);
  box-shadow: 0 6px 20px rgba(46, 204, 113, 0.5);
}

.translate-btn {
  background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
  color: white;
}

.translate-btn:hover {
  transform: scale(1.15);
  box-shadow: 0 6px 20px rgba(52, 152, 219, 0.5);
}

/* 伴读模式底部区域 */
.accompany-mode-footer {
  margin-bottom: 30px;
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.parent-tip {
  display: flex;
  gap: 15px;
  padding: 20px;
  background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%);
  border-radius: 16px;
  border-left: 4px solid #ffc107;
}

/* 跟读反馈区域 */
.follow-read-result {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 20px;
  background: linear-gradient(135deg, #d1ecf1 0%, #bee5eb 100%);
  border-radius: 16px;
  border-left: 4px solid #17a2b8;
  animation: slideIn 0.3s ease;
  transition: all 0.3s ease;
}

.result-clickable-area {
  display: flex;
  gap: 15px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.result-clickable-area:hover {
  transform: translateY(-2px);
}

.follow-read-result:hover {
  box-shadow: 0 4px 12px rgba(23, 162, 184, 0.3);
  background: linear-gradient(135deg, #bee5eb 0%, #a0d8e8 100%);
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.result-icon {
  font-size: 32px;
  flex-shrink: 0;
}

.result-content {
  flex: 1;
}

.result-title {
  font-size: 18px;
  font-weight: 600;
  color: #0c5460;
  margin-bottom: 8px;
}

.result-score {
  font-size: 16px;
  color: #0c5460;
  margin-bottom: 5px;
  font-weight: 500;
}

.result-feedback {
  font-size: 14px;
  color: #0c5460;
  line-height: 1.6;
  opacity: 0.9;
}

.result-history-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(12, 84, 96, 0.2);
}

.history-btn {
  width: 32px;
  height: 32px;
  border: 1px solid #17a2b8;
  background: white;
  color: #17a2b8;
  border-radius: 6px;
  cursor: pointer;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.history-btn:hover:not(:disabled) {
  background: #17a2b8;
  color: white;
  transform: scale(1.1);
}

.history-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.history-indicator {
  font-size: 13px;
  color: #0c5460;
  font-weight: 500;
  min-width: 60px;
  text-align: center;
}

.result-good {
  color: #28a745;
}

.result-need-improve {
  color: #ffc107;
}

.tip-icon {
  font-size: 32px;
  flex-shrink: 0;
}

.tip-content {
  flex: 1;
}

.tip-title {
  font-size: 18px;
  font-weight: 600;
  color: #856404;
  margin-bottom: 8px;
}

.tip-text {
  font-size: 16px;
  color: #856404;
  line-height: 1.6;
}

.reader-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding-top: 20px;
  border-top: 2px solid #e0e0e0;
}

.control-btn {
  padding: 12px 24px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
  border-radius: 12px;
  color: white;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
}

.control-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}

.control-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.page-indicator {
  display: flex;
  gap: 8px;
  align-items: center;
}

.page-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #e0e0e0;
  cursor: pointer;
  transition: all 0.3s ease;
}

.page-dot:hover {
  background: #667eea;
  transform: scale(1.2);
}

.page-dot.active {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  width: 16px;
  height: 16px;
}

/* 阅读报告界面 */
.report-container {
  max-width: 1200px;
  margin: 0 auto;
}

.report-card {
  background: white;
  border-radius: 24px;
  padding: 40px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}

.report-overview {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 30px;
  margin-bottom: 40px;
}

.stat-badge {
  background: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%);
  border-radius: 16px;
  padding: 20px;
  display: flex;
  align-items: center;
  gap: 15px;
  box-shadow: 0 4px 12px rgba(255, 215, 0, 0.25);
  transition: all 0.3s ease;
}

.stat-badge.clickable {
  cursor: pointer;
}

.stat-badge.clickable:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(255, 215, 0, 0.35);
}

.badge-icon {
  font-size: 40px;
  flex-shrink: 0;
}

.badge-content {
  flex: 1;
}

.badge-value {
  font-size: 32px;
  font-weight: 700;
  color: #856404;
  margin-bottom: 4px;
}

.badge-label {
  font-size: 14px;
  color: #856404;
  font-weight: 600;
}

.stat-gauge {
  background: #f8f9fa;
  border-radius: 16px;
  padding: 20px;
  border: 2px solid #e0e0e0;
  transition: all 0.3s ease;
}

.stat-gauge.clickable {
  cursor: pointer;
}

.stat-gauge.clickable:hover {
  transform: translateY(-2px);
  border-color: #667eea;
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);
}

.gauge-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 15px;
  font-size: 16px;
  font-weight: 600;
  color: #2c3e50;
}

.gauge-icon {
  font-size: 20px;
}

.gauge-container {
  display: flex;
  justify-content: center;
  align-items: center;
}

.gauge-circle {
  position: relative;
  width: 140px;
  height: 140px;
}

.gauge-svg {
  width: 100%;
  height: 100%;
}

.gauge-bg {
  stroke: #e0e0e0;
}

.gauge-fill {
  stroke: #667eea;
  transition: stroke-dasharray 0.5s ease;
}

.gauge-value {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 28px;
  font-weight: 700;
  color: #667eea;
}

.report-details {
  margin-top: 30px;
  animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.details-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}

.details-title {
  font-size: 20px;
  font-weight: 600;
  color: #2c3e50;
  margin: 0;
}

.close-details-btn {
  width: 32px;
  height: 32px;
  border: none;
  background: #f0f0f0;
  border-radius: 50%;
  font-size: 20px;
  color: #666;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.close-details-btn:hover {
  background: #e0e0e0;
  color: #333;
}

.reading-records {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.record-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 16px;
  border: 2px solid #e0e0e0;
  transition: all 0.3s ease;
}

.record-item:hover {
  border-color: #667eea;
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.1);
}

.record-book-info {
  display: flex;
  align-items: center;
  gap: 15px;
  flex: 1;
}

.record-cover {
  width: 80px;
  height: 100px;
  border-radius: 8px;
  overflow: hidden;
  flex-shrink: 0;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  background-size: cover;
  background-position: center;
  background-color: #f0f0f0;
}

.record-cover .cover-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.record-cover .cover-icon {
  font-size: 32px;
}

.record-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.record-info {
  flex: 1;
}

.record-title {
  font-size: 18px;
  font-weight: 600;
  color: #2c3e50;
  margin-bottom: 8px;
}

.record-date {
  font-size: 14px;
  color: #7f8c8d;
}

.record-scores {
  display: flex;
  gap: 15px;
  align-items: center;
}

.score-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
}

.score-label {
  font-size: 12px;
  color: #7f8c8d;
}

.score-value {
  font-size: 20px;
  font-weight: 700;
  padding: 6px 12px;
  border-radius: 8px;
}

.score-excellent {
  background: #d4edda;
  color: #155724;
}

.score-good {
  background: #d1ecf1;
  color: #0c5460;
}

.score-fair {
  background: #fff3cd;
  color: #856404;
}

.score-poor {
  background: #f8d7da;
  color: #721c24;
}

/* 跟读详情样式 */
.accuracy-details {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.accuracy-record-item {
  padding: 20px;
  background: #f8f9fa;
  border-radius: 16px;
  border: 2px solid #e0e0e0;
  transition: all 0.3s ease;
}

.accuracy-record-item:hover {
  border-color: #667eea;
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.1);
}

.accuracy-book-header {
  display: flex;
  align-items: center;
  gap: 15px;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid #e0e0e0;
}

.accuracy-book-cover {
  width: 60px;
  height: 75px;
  border-radius: 8px;
  overflow: hidden;
  flex-shrink: 0;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
  background-size: cover;
  background-position: center;
  background-color: #f0f0f0;
}

.accuracy-book-cover .cover-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.accuracy-book-cover .cover-icon {
  font-size: 24px;
}

.accuracy-book-info {
  flex: 1;
}

.accuracy-book-title {
  font-size: 18px;
  font-weight: 600;
  color: #2c3e50;
  margin-bottom: 5px;
}

.accuracy-book-date {
  font-size: 14px;
  color: #7f8c8d;
}

.accuracy-scores-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.accuracy-score-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: white;
  border-radius: 12px;
  border: 1px solid #e0e0e0;
}

.accuracy-attempt {
  font-size: 14px;
  color: #7f8c8d;
  font-weight: 500;
}

.accuracy-score-value {
  display: flex;
  align-items: center;
  gap: 10px;
}

.accuracy-score-value .score-number {
  font-size: 20px;
  font-weight: 700;
}

.accuracy-score-value .score-status {
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 6px;
  background: rgba(102, 126, 234, 0.1);
  color: #667eea;
}

.accuracy-score-value.score-excellent .score-status {
  background: rgba(46, 213, 115, 0.1);
  color: #2ed573;
}

.accuracy-score-value.score-good .score-status {
  background: rgba(102, 126, 234, 0.1);
  color: #667eea;
}

.accuracy-score-value.score-fair .score-status {
  background: rgba(255, 184, 0, 0.1);
  color: #ffb800;
}

.accuracy-score-value.score-poor .score-status {
  background: rgba(255, 107, 107, 0.1);
  color: #ff6b6b;
}

/* 跟读模态框样式 */
.follow-read-modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.follow-read-modal {
  background: white;
  border-radius: 20px;
  width: 90%;
  max-width: 600px;
  max-height: 80vh;
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
  animation: slideUp 0.3s ease;
}

@keyframes slideUp {
  from {
    transform: translateY(30px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 30px;
  border-bottom: 2px solid #e9ecef;
}

.modal-header h3 {
  margin: 0;
  font-size: 22px;
  font-weight: 600;
  color: #2c3e50;
}

.modal-close-btn {
  width: 32px;
  height: 32px;
  border: none;
  background: #f8f9fa;
  border-radius: 50%;
  font-size: 24px;
  color: #6c757d;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
}

.modal-close-btn:hover {
  background: #e9ecef;
  color: #2c3e50;
}

.modal-content {
  padding: 30px;
}

.sentence-to-read {
  margin-bottom: 30px;
  text-align: center;
}

.sentence-label {
  font-size: 16px;
  color: #6c757d;
  margin-bottom: 15px;
}

.sentence-text-large {
  font-size: 22px;
  line-height: 1.6;
  color: #2c3e50;
  font-weight: 500;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
  border: 2px solid #e9ecef;
}

.page-text-large {
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
  border: 2px solid #e9ecef;
  max-height: 300px;
  overflow-y: auto;
}

.page-sentence-item {
  font-size: 20px;
  line-height: 1.8;
  color: #2c3e50;
  font-weight: 500;
  margin-bottom: 15px;
  padding: 12px;
  background: white;
  border-radius: 8px;
  border-left: 4px solid #667eea;
}

.page-sentence-item:last-child {
  margin-bottom: 0;
}

.recording-status {
  text-align: center;
  padding: 20px;
}

.recording-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 15px;
  font-size: 18px;
  font-weight: 600;
  color: #dc3545;
}

.recording-dot {
  width: 12px;
  height: 12px;
  background: #dc3545;
  border-radius: 50%;
  animation: pulse 1.5s infinite;
}

@keyframes pulse {
  0%, 100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.5;
    transform: scale(1.2);
  }
}

.recording-hint {
  font-size: 14px;
  color: #6c757d;
}

.recording-prompt {
  text-align: center;
  padding: 40px 20px;
}

.prompt-icon {
  font-size: 48px;
  margin-bottom: 15px;
}

.prompt-text {
  font-size: 16px;
  color: #6c757d;
  margin-bottom: 10px;
}

.countdown-timer {
  font-size: 48px;
  font-weight: 700;
  color: #667eea;
  margin-top: 15px;
  animation: pulse 1s infinite;
}

@keyframes pulse {
  0%, 100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.2);
    opacity: 0.8;
  }
}

.recognition-result {
  text-align: center;
  padding: 20px;
}

.result-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-bottom: 20px;
}

.result-icon-large {
  font-size: 48px;
}

.result-title-large {
  font-size: 24px;
  font-weight: 600;
  color: #2c3e50;
}

.result-score-large {
  font-size: 32px;
  font-weight: 700;
  color: #667eea;
  margin-bottom: 15px;
}

.result-feedback-large {
  font-size: 16px;
  color: #6c757d;
  margin-bottom: 20px;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 10px;
}

.result-details {
  text-align: left;
  margin-top: 20px;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 10px;
}

.detail-item {
  margin-bottom: 10px;
}

.detail-label {
  font-weight: 600;
  color: #495057;
  margin-right: 8px;
}

.detail-value {
  color: #6c757d;
  word-break: break-word;
}

/* 单词级别发音评测样式 */
.word-scores {
  margin-top: 20px;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 10px;
}

.word-scores-title {
  font-weight: 600;
  color: #495057;
  margin-bottom: 12px;
  font-size: 14px;
}

.word-scores-content {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.word-score-item-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-width: 80px;
}

.word-score-item {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.2s ease;
  cursor: help;
  white-space: nowrap;
}

.word-meaning {
  font-size: 12px;
  color: #6c757d;
  text-align: center;
  padding: 2px 6px;
  background: #f8f9fa;
  border-radius: 4px;
  min-height: 18px;
  line-height: 1.4;
}

.word-score-item.word-clickable {
  cursor: pointer;
  position: relative;
}

.word-score-item.word-clickable:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.word-score-item.word-clickable:active {
  transform: translateY(0);
}

.word-play-icon {
  font-size: 12px;
  margin-left: 2px;
  opacity: 0.8;
  transition: opacity 0.2s ease;
}

.word-score-item.word-clickable:hover .word-play-icon {
  opacity: 1;
}

.word-score-excellent {
  background: #d4edda;
  color: #155724;
  border: 1px solid #c3e6cb;
}

.word-score-good {
  background: #d1ecf1;
  color: #0c5460;
  border: 1px solid #bee5eb;
}

.word-score-fair {
  background: #fff3cd;
  color: #856404;
  border: 1px solid #ffeaa7;
}

.word-score-poor {
  background: #f8d7da;
  color: #721c24;
  border: 1px solid #f5c6cb;
  font-weight: 600;
  animation: pulse-warning 2s infinite;
}

@keyframes pulse-warning {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.8;
  }
}

.modal-footer {
  display: flex;
  justify-content: center;
  gap: 15px;
  padding: 20px 30px;
  border-top: 2px solid #e9ecef;
}

.modal-btn {
  padding: 12px 30px;
  border: none;
  border-radius: 12px;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
}

.start-btn {
  background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
  color: white;
}

.start-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(46, 204, 113, 0.4);
}

.stop-btn {
  background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
  color: white;
}

.stop-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(231, 76, 60, 0.4);
}

.close-btn {
  background: #6c757d;
  color: white;
}

.close-btn:hover {
  background: #5a6268;
  transform: translateY(-2px);
}

/* 响应式设计 */
@media (max-width: 1024px) {
  .reader-content {
    grid-template-columns: 1fr;
    gap: 30px;
  }

  .reader-image-section {
    position: static;
  }

  .book-image {
    max-width: 100%;
  }

  .reader-header {
    flex-wrap: wrap;
    gap: 15px;
  }

  .reader-title-section {
    width: 100%;
    order: 2;
  }

  .reader-header-right {
    width: 100%;
    justify-content: space-between;
    order: 3;
  }

  .reader-back-btn {
    order: 1;
  }

  .mode-options {
    grid-template-columns: 1fr;
  }

  .report-overview {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .books-grid {
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 20px;
  }

  .reader-card {
    padding: 20px;
  }

  .record-item {
    flex-direction: column;
    align-items: flex-start;
  }

  .record-scores {
    width: 100%;
    justify-content: flex-start;
  }
}

/* 发音详情模态框样式 */
.pronunciation-details-modal {
  max-width: 600px;
  max-height: 80vh;
  overflow-y: auto;
}

.pronunciation-summary {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 20px;
  background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
  border-radius: 12px;
  margin-bottom: 20px;
}

.summary-icon {
  font-size: 48px;
  flex-shrink: 0;
}

.summary-content {
  flex: 1;
}

.summary-title {
  font-size: 24px;
  font-weight: 600;
  color: #1976d2;
  margin-bottom: 8px;
}

.summary-score {
  font-size: 20px;
  font-weight: 600;
  color: #1565c0;
  margin-bottom: 8px;
}

.summary-feedback {
  font-size: 16px;
  color: #424242;
  line-height: 1.5;
}

.pronunciation-details-section {
  margin-bottom: 20px;
}

.details-item {
  margin-bottom: 15px;
  padding: 12px;
  background: #f5f5f5;
  border-radius: 8px;
}

.details-item.audio-playback {
  display: flex;
  align-items: center;
  gap: 10px;
}

.play-recording-btn {
  padding: 8px 16px;
  background: #667eea;
  color: white;
  border: none;
  border-radius: 6px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  gap: 6px;
}

.play-recording-btn:hover {
  background: #5568d3;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
}

.play-recording-btn:active {
  transform: translateY(0);
}

.details-label {
  font-weight: 600;
  color: #666;
  margin-bottom: 6px;
  font-size: 14px;
}

.details-value {
  color: #333;
  font-size: 15px;
  line-height: 1.6;
  word-break: break-word;
}

.word-score-badge {
  font-size: 11px;
  margin-left: 4px;
  padding: 2px 6px;
  background: rgba(0, 0, 0, 0.1);
  border-radius: 10px;
  font-weight: 600;
}

.click-hint {
  font-size: 12px;
  color: #666;
  margin-left: 8px;
  font-weight: normal;
  opacity: 0.7;
}

.follow-read-result.clickable:hover .click-hint {
  opacity: 1;
  color: #0c5460;
}

.result-history-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(12, 84, 96, 0.2);
}

.history-btn {
  width: 32px;
  height: 32px;
  border: 1px solid #17a2b8;
  background: white;
  color: #17a2b8;
  border-radius: 6px;
  cursor: pointer;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.history-btn:hover:not(:disabled) {
  background: #17a2b8;
  color: white;
  transform: scale(1.1);
}

.history-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.history-indicator {
  font-size: 13px;
  color: #0c5460;
  font-weight: 500;
  min-width: 60px;
  text-align: center;
}
</style>
